mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-11 08:10:58 +00:00
- improved error logging capability
git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@86 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
66489c3733
commit
76e4066e94
@ -48,7 +48,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMIX Jim Wigginton
|
* @copyright MMIX Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: SFTP.php,v 1.15 2010-02-11 16:17:40 terrafrost Exp $
|
* @version $Id: SFTP.php,v 1.16 2010-02-12 23:02:13 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -202,6 +202,16 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
*/
|
*/
|
||||||
var $packet_log = array();
|
var $packet_log = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error information
|
||||||
|
*
|
||||||
|
* @see Net_SFTP::getSFTPErrors()
|
||||||
|
* @see Net_SFTP::getLastSFTPError()
|
||||||
|
* @var String
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $errors = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
@ -253,7 +263,14 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
);
|
);
|
||||||
$this->status_codes = array(
|
$this->status_codes = array(
|
||||||
0 => 'NET_SFTP_STATUS_OK',
|
0 => 'NET_SFTP_STATUS_OK',
|
||||||
1 => 'NET_SFTP_STATUS_EOF'
|
1 => 'NET_SFTP_STATUS_EOF',
|
||||||
|
2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
|
||||||
|
3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',
|
||||||
|
4 => 'NET_SFTP_STATUS_FAILURE',
|
||||||
|
5 => 'NET_SFTP_STATUS_BAD_MESSAGE',
|
||||||
|
6 => 'NET_SFTP_STATUS_NO_CONNECTION',
|
||||||
|
7 => 'NET_SFTP_STATUS_CONNECTION_LOST',
|
||||||
|
8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED'
|
||||||
);
|
);
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
|
||||||
// the order, in this case, matters quite a lot - see Net_SFTP::_parseAttributes() to understand why
|
// the order, in this case, matters quite a lot - see Net_SFTP::_parseAttributes() to understand why
|
||||||
@ -477,10 +494,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$realpath = $this->_string_shift($response, $length);
|
$realpath = $this->_string_shift($response, $length);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
// skip over the status code - hopefully the error message will give us all the info we need, anyway
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
$this->_string_shift($response, 4);
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
|
||||||
$this->debug_info.= "\r\n\r\nSSH_FXP_STATUS:\r\n" . $this->_string_shift($response, $length);
|
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
@ -522,6 +537,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$handle = substr($response, 4);
|
$handle = substr($response, 4);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
@ -532,12 +549,19 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$this->pwd = $dir;
|
$this->pwd = $dir;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -575,6 +599,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
@ -608,7 +634,7 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_EOF) {
|
if ($status != NET_SFTP_STATUS_EOF) {
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_FXP_STATUS:\r\n" . $this->_string_shift($response, $length);
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break 2;
|
break 2;
|
||||||
@ -624,12 +650,19 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
|
|
||||||
// "The client MUST release all resources associated with the handle regardless of the status."
|
// "The client MUST release all resources associated with the handle regardless of the status."
|
||||||
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $contents;
|
return $contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,12 +701,18 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
|
|
||||||
-- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
|
-- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
|
||||||
*/
|
*/
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_EOF) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
}
|
||||||
|
|
||||||
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
||||||
// tell us if the file actually exists.
|
// tell us if the file actually exists.
|
||||||
// incidentally ,SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
// incidentally ,SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
||||||
@ -688,6 +727,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$attrs = $this->_parseAttributes($response);
|
$attrs = $this->_parseAttributes($response);
|
||||||
return $attrs['permissions'];
|
return $attrs['permissions'];
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,7 +769,7 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
if ($status != NET_SFTP_STATUS_OK) {
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_FXP_STATUS:\r\n" . $this->_string_shift($response, $length);
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,6 +807,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_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?
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,9 +858,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$handle = substr($response, 4);
|
$handle = substr($response, 4);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
$this->_string_shift($response, 4);
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
$this->debug_info.= "\r\n\r\nSSH_FXP_STATUS:\r\n" . $this->_string_shift($response, $length);
|
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
@ -857,12 +899,18 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($i-- > 0){
|
while ($i--) {
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mode == NET_SFTP_LOCAL_FILE) {
|
if ($mode == NET_SFTP_LOCAL_FILE) {
|
||||||
@ -873,12 +921,19 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,6 +971,8 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$handle = substr($response, 4);
|
$handle = substr($response, 4);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
@ -933,13 +990,14 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$attrs = $this->_parseAttributes($response);
|
$attrs = $this->_parseAttributes($response);
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($local_file !== false) {
|
if ($local_file !== false) {
|
||||||
$fp = fopen($local_file, 'w');
|
$fp = fopen($local_file, 'w');
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
@ -968,10 +1026,9 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NET_SFTP_STATUS:
|
case NET_SFTP_STATUS:
|
||||||
$this->_string_shift($response, 4);
|
extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
$this->debug_info.= "\r\n\r\nSSH_FXP_STATUS:\r\n" . $this->_string_shift($response, $length);
|
break 2;
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
@ -982,12 +1039,19 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($content)) {
|
if (isset($content)) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
@ -1025,10 +1089,15 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
|
||||||
|
|
||||||
// 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
|
||||||
return $status == NET_SFTP_STATUS_OK;
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1063,10 +1132,15 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
|
||||||
|
|
||||||
// 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
|
||||||
return $status == NET_SFTP_STATUS_OK;
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
|
if ($status != NET_SFTP_STATUS_OK) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
|
$this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1198,12 +1272,6 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
|
|
||||||
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
||||||
|
|
||||||
if (defined('NET_SFTP_LOGGING')) {
|
|
||||||
$this->packet_type_log[] = '<- ' . $this->packet_types[$this->packet_type] .
|
|
||||||
' (' . round($stop - $start, 4) . 's)';
|
|
||||||
$this->packet_log[] = $packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->request_id !== false) {
|
if ($this->request_id !== false) {
|
||||||
$this->_string_shift($this->packet_buffer, 4); // remove the request id
|
$this->_string_shift($this->packet_buffer, 4); // remove the request id
|
||||||
$length-= 5; // account for the request id and the packet type
|
$length-= 5; // account for the request id and the packet type
|
||||||
@ -1211,7 +1279,15 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
$length-= 1; // account for the packet type
|
$length-= 1; // account for the packet type
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_string_shift($this->packet_buffer, $length);
|
$packet = $this->_string_shift($this->packet_buffer, $length);
|
||||||
|
|
||||||
|
if (defined('NET_SFTP_LOGGING')) {
|
||||||
|
$this->packet_type_log[] = '<- ' . $this->packet_types[$this->packet_type] .
|
||||||
|
' (' . round($stop - $start, 4) . 's)';
|
||||||
|
$this->packet_log[] = $packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1239,6 +1315,28 @@ class Net_SFTP extends Net_SSH2 {
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all errors
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getSFTPErrors()
|
||||||
|
{
|
||||||
|
return $this->sftp_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last error
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getLastSFTPError()
|
||||||
|
{
|
||||||
|
return $this->sftp_errors[count($this->sftp_errors) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get supported SFTP versions
|
* Get supported SFTP versions
|
||||||
*
|
*
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright MMVII Jim Wigginton
|
* @copyright MMVII Jim Wigginton
|
||||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||||
* @version $Id: SSH2.php,v 1.36 2010-02-11 07:02:51 terrafrost Exp $
|
* @version $Id: SSH2.php,v 1.37 2010-02-12 23:02:13 terrafrost Exp $
|
||||||
* @link http://phpseclib.sourceforge.net
|
* @link http://phpseclib.sourceforge.net
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -176,13 +176,14 @@ class Net_SSH2 {
|
|||||||
var $bitmap = 0;
|
var $bitmap = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug Info
|
* Error information
|
||||||
*
|
*
|
||||||
* @see Net_SSH2::getDebugInfo()
|
* @see Net_SSH2::getErrors()
|
||||||
|
* @see Net_SSH2::getLastError()
|
||||||
* @var String
|
* @var String
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $debug_info = '';
|
var $errors = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Identifier
|
* Server Identifier
|
||||||
@ -637,7 +638,7 @@ class Net_SSH2 {
|
|||||||
$temp = '';
|
$temp = '';
|
||||||
while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {
|
while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {
|
||||||
if (substr($temp, -2) == "\r\n") {
|
if (substr($temp, -2) == "\r\n") {
|
||||||
$this->debug_info.= $temp;
|
$this->errors[] = $temp;
|
||||||
$temp = '';
|
$temp = '';
|
||||||
}
|
}
|
||||||
$temp.= fgets($this->fsock, 255);
|
$temp.= fgets($this->fsock, 255);
|
||||||
@ -665,7 +666,7 @@ class Net_SSH2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->server_identifier = trim($temp);
|
$this->server_identifier = trim($temp);
|
||||||
$this->debug_info = utf8_decode($this->debug_info);
|
$this->errors[] = utf8_decode($this->debug_info);
|
||||||
|
|
||||||
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
||||||
user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE);
|
user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE);
|
||||||
@ -1400,7 +1401,7 @@ class Net_SSH2 {
|
|||||||
$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';
|
||||||
}
|
}
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_USERAUTH_PASSWD_CHANGEREQ:\r\n" . utf8_decode($this->_string_shift($response, $length));
|
$this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_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:
|
||||||
// either the login is bad or the server employees multi-factor authentication
|
// either the login is bad or the server employees multi-factor authentication
|
||||||
@ -1462,7 +1463,7 @@ class Net_SSH2 {
|
|||||||
switch ($type) {
|
switch ($type) {
|
||||||
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
case NET_SSH2_MSG_USERAUTH_FAILURE:
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_USERAUTH_FAILURE:\r\n" . $this->_string_shift($response, $length);
|
$this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_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_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
|
||||||
@ -1675,7 +1676,7 @@ class Net_SSH2 {
|
|||||||
case NET_SSH2_MSG_DISCONNECT:
|
case NET_SSH2_MSG_DISCONNECT:
|
||||||
$this->_string_shift($payload, 1);
|
$this->_string_shift($payload, 1);
|
||||||
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_DISCONNECT:\r\n" . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
||||||
$this->bitmask = 0;
|
$this->bitmask = 0;
|
||||||
return false;
|
return false;
|
||||||
case NET_SSH2_MSG_IGNORE:
|
case NET_SSH2_MSG_IGNORE:
|
||||||
@ -1684,7 +1685,7 @@ class Net_SSH2 {
|
|||||||
case NET_SSH2_MSG_DEBUG:
|
case NET_SSH2_MSG_DEBUG:
|
||||||
$this->_string_shift($payload, 2);
|
$this->_string_shift($payload, 2);
|
||||||
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_DEBUG:\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
|
||||||
$payload = $this->_get_binary_packet();
|
$payload = $this->_get_binary_packet();
|
||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_UNIMPLEMENTED:
|
case NET_SSH2_MSG_UNIMPLEMENTED:
|
||||||
@ -1703,7 +1704,7 @@ class Net_SSH2 {
|
|||||||
if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && !($this->bitmap & NET_SSH2_MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && !($this->bitmap & NET_SSH2_MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
|
||||||
$this->_string_shift($payload, 1);
|
$this->_string_shift($payload, 1);
|
||||||
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_USERAUTH_BANNER:\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_USERAUTH_BANNER: ' . utf8_decode($this->_string_shift($payload, $length));
|
||||||
$payload = $this->_get_binary_packet();
|
$payload = $this->_get_binary_packet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1713,7 +1714,7 @@ class Net_SSH2 {
|
|||||||
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
|
||||||
$this->_string_shift($payload, 1);
|
$this->_string_shift($payload, 1);
|
||||||
extract(unpack('Nlength', $this->_string_shift($payload)));
|
extract(unpack('Nlength', $this->_string_shift($payload)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_GLOBAL_REQUEST:\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . utf8_decode($this->_string_shift($payload, $length));
|
||||||
|
|
||||||
if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
|
if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
@ -1724,7 +1725,7 @@ class Net_SSH2 {
|
|||||||
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
|
||||||
$this->_string_shift($payload, 1);
|
$this->_string_shift($payload, 1);
|
||||||
extract(unpack('N', $this->_string_shift($payload, 4)));
|
extract(unpack('N', $this->_string_shift($payload, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_CHANNEL_OPEN:\r\n" . utf8_decode($this->_string_shift($payload, $length));
|
$this->errors[] = 'SSH_MSG_CHANNEL_OPEN: ' . utf8_decode($this->_string_shift($payload, $length));
|
||||||
|
|
||||||
$this->_string_shift($payload, 4); // skip over client channel
|
$this->_string_shift($payload, 4); // skip over client channel
|
||||||
extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
|
extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
|
||||||
@ -1825,7 +1826,7 @@ class Net_SSH2 {
|
|||||||
$data = $this->_string_shift($response, $length);
|
$data = $this->_string_shift($response, $length);
|
||||||
switch ($data_type_code) {
|
switch ($data_type_code) {
|
||||||
case NET_SSH2_EXTENDED_DATA_STDERR:
|
case NET_SSH2_EXTENDED_DATA_STDERR:
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_CHANNEL_EXTENDED_DATA (SSH_EXTENDED_DATA_STDERR):\r\n" . $data;
|
$this->errors[] = 'SSH_MSG_CHANNEL_EXTENDED_DATA (SSH_EXTENDED_DATA_STDERR): ' . $data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||||
@ -1835,10 +1836,12 @@ class Net_SSH2 {
|
|||||||
case 'exit-signal':
|
case 'exit-signal':
|
||||||
$this->_string_shift($response, 1);
|
$this->_string_shift($response, 1);
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n\r\nSSH_MSG_CHANNEL_REQUEST (exit-signal):\r\nSIG" . $this->_string_shift($response, $length);
|
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
|
||||||
$this->_string_shift($response, 1);
|
$this->_string_shift($response, 1);
|
||||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||||
$this->debug_info.= "\r\n" . $this->_string_shift($response, $length);
|
if ($length) {
|
||||||
|
$this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
|
||||||
|
}
|
||||||
//case 'exit-status':
|
//case 'exit-status':
|
||||||
default:
|
default:
|
||||||
// "Some systems may not implement signals, in which case they SHOULD ignore this message."
|
// "Some systems may not implement signals, in which case they SHOULD ignore this message."
|
||||||
@ -2072,16 +2075,25 @@ class Net_SSH2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Debug Information
|
* Returns all errors
|
||||||
*
|
|
||||||
* If any debug information is sent by the server, this function can be used to access it.
|
|
||||||
*
|
*
|
||||||
* @return String
|
* @return String
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function getDebugInfo()
|
function getErrors()
|
||||||
{
|
{
|
||||||
return $this->debug_info;
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last error
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getLastError()
|
||||||
|
{
|
||||||
|
return $this->errors[count($this->errors) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user