mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-05-29 06:30:51 +00:00
add setPreferredVersion() and other changes
This commit is contained in:
parent
bf88ba4382
commit
4cb6bcb75e
|
@ -321,6 +321,22 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
var $channel_close = false;
|
||||
|
||||
/**
|
||||
* Has the SFTP channel been partially negotiated?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $partial_init = false;
|
||||
|
||||
/**
|
||||
* Has the SFTP channel been fully negotiated?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $full_init = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
|
@ -426,6 +442,7 @@ class Net_SFTP extends Net_SSH2
|
|||
0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT',
|
||||
0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE',
|
||||
0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT',
|
||||
0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME',
|
||||
0x00008000 => 'NET_SFTP_ATTR_CTIME',
|
||||
// 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
|
||||
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
|
||||
|
@ -490,32 +507,31 @@ class Net_SFTP extends Net_SSH2
|
|||
}
|
||||
|
||||
/**
|
||||
* Login
|
||||
* Check a few things before SFTP functions are called
|
||||
*
|
||||
* @param string $username
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function login($username)
|
||||
function _precheck()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$callback = version_compare(PHP_VERSION, '5.3.0') < 0 ?
|
||||
array(&$this, 'parent::login') :
|
||||
'parent::login';
|
||||
if (!call_user_func_array($callback, $args)) {
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_init_sftp_connection();
|
||||
if (!$this->full_init) {
|
||||
return $this->_init_sftp_connection();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)initializes the SFTP channel
|
||||
* Partiailly initialize an SFTP connection
|
||||
*
|
||||
* @return bool
|
||||
* @access private
|
||||
* @access public
|
||||
*/
|
||||
function _init_sftp_connection()
|
||||
function _partial_init_sftp_connection()
|
||||
{
|
||||
$this->window_size_server_to_client[NET_SFTP_CHANNEL] = $this->window_size;
|
||||
|
||||
|
@ -619,6 +635,23 @@ class Net_SFTP extends Net_SSH2
|
|||
$this->extensions[$key] = $value;
|
||||
}
|
||||
|
||||
$this->partial_init = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)initializes the SFTP channel
|
||||
*
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _init_sftp_connection()
|
||||
{
|
||||
if (!$this->partial_init && !$this->_partial_init_sftp_connection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
A Note on SFTPv4/5/6 support:
|
||||
<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:
|
||||
|
@ -642,9 +675,14 @@ class Net_SFTP extends Net_SSH2
|
|||
in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what Net_SFTP would do is close the
|
||||
channel and reopen it with a new and updated SSH_FXP_INIT packet.
|
||||
*/
|
||||
if (isset($this->extensions['versions'])) {
|
||||
if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) {
|
||||
$versions = explode(',', $this->extensions['versions']);
|
||||
foreach ([6, 5, 4] as $ver) {
|
||||
$supported = [6, 5, 4];
|
||||
if ($this->preferredVersion) {
|
||||
$supported = array_diff($supported, [$this->preferredVersion]);
|
||||
array_unshift($supported, $this->preferredVersion);
|
||||
}
|
||||
foreach ($supported as $ver) {
|
||||
if (in_array($ver, $versions)) {
|
||||
if ($ver === $this->version) {
|
||||
break;
|
||||
|
@ -880,7 +918,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function chdir($dir)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1037,7 +1075,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function _list($dir, $raw = true)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1092,13 +1130,17 @@ class Net_SFTP extends Net_SSH2
|
|||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$shortname = $this->_string_shift($response, $length);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
// SFTPv4 "removed the long filename from the names structure-- it can now be
|
||||
// built from information available in the attrs structure."
|
||||
if ($this->version == 3) {
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$longname = $this->_string_shift($response, $length);
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$longname = $this->_string_shift($response, $length);
|
||||
$attributes = $this->_parseAttributes($response);
|
||||
if (!isset($attributes['type'])) {
|
||||
if (!isset($attributes['type']) && $this->version == 3) {
|
||||
$fileType = $this->_parseLongname($longname);
|
||||
if ($fileType) {
|
||||
$attributes['type'] = $fileType;
|
||||
|
@ -1258,7 +1300,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function size($filename)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1378,7 +1420,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function stat($filename)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1435,7 +1477,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function lstat($filename)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1549,7 +1591,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function touch($filename, $time = null, $atime = null)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1600,6 +1642,8 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function chown($filename, $uid, $recursive = false)
|
||||
{
|
||||
// from v3 to v4 they made this a string
|
||||
//"Made file attribute owner and group strings so they can actually be used on disparate systems."
|
||||
//zzzzzzzzz
|
||||
// quoting from <http://www.kernel.org/doc/man-pages/online/pages/man2/chown.2.html>,
|
||||
// "if the owner or group is specified as -1, then that ID is not changed"
|
||||
|
@ -1621,6 +1665,9 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function chgrp($filename, $gid, $recursive = false)
|
||||
{
|
||||
// from v3 to v4 they made this a string
|
||||
//"Made file attribute owner and group strings so they can actually be used on disparate systems."
|
||||
//zzzzzzzzz
|
||||
$attr = pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid);
|
||||
|
||||
return $this->_setstat($filename, $attr, $recursive);
|
||||
|
@ -1688,7 +1735,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function _setstat($filename, $attr, $recursive)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1818,7 +1865,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function readlink($link)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1868,7 +1915,14 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function symlink($target, $link)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
/*
|
||||
SFTP v6 changes (from v5)
|
||||
o Changed the SYMLINK packet to be LINK and give it the ability to
|
||||
create hard links. Also change it's packet number because many
|
||||
implementation implemented SYMLINK with the arguments reversed.
|
||||
Hopefully the new argument names make it clear which way is which.
|
||||
*/
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1909,7 +1963,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function mkdir($dir, $mode = -1, $recursive = false)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1978,7 +2032,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function rmdir($dir)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2085,7 +2139,7 @@ class Net_SFTP extends Net_SSH2
|
|||
none of these are currently supported
|
||||
*/
|
||||
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2327,7 +2381,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2438,6 +2492,7 @@ class Net_SFTP extends Net_SSH2
|
|||
}
|
||||
// maybe the file was successfully transferred, maybe it wasn't
|
||||
if ($this->channel_close) {
|
||||
$this->partial_init = false;
|
||||
$this->_init_sftp_connection();
|
||||
return false;
|
||||
} else {
|
||||
|
@ -2487,7 +2542,7 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function delete($path, $recursive = true)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2923,7 +2978,12 @@ class Net_SFTP extends Net_SSH2
|
|||
*/
|
||||
function rename($oldname, $newname)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
// in SFTP v5+
|
||||
// Add support for better control of the rename operation.
|
||||
// so we'll just need to add \0\0\0\0 after
|
||||
// by default if the destination file already exists it fails
|
||||
// but in v5+ you can pass a SSH_FXF_RENAME_OVERWRITE flag
|
||||
if (!$this->_precheck()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3414,6 +3474,10 @@ class Net_SFTP extends Net_SSH2
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!$this->partial_init) {
|
||||
$this->_partial_init_sftp_connection();
|
||||
}
|
||||
|
||||
$temp = array('version' => $this->version);
|
||||
if (isset($this->extensions['versions'])) {
|
||||
$temp['extensions'] = $this->extensions['versions'];
|
||||
|
@ -3421,6 +3485,21 @@ class Net_SFTP extends Net_SSH2
|
|||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set preferred version
|
||||
*
|
||||
* If you're preferred version isn't supported then the highest supported
|
||||
* version of SFTP will be utilized. Set to null or false or int(0) to
|
||||
* unset the preferred version
|
||||
*
|
||||
* @param int $version
|
||||
* @access public
|
||||
*/
|
||||
function setPreferredVersion($version)
|
||||
{
|
||||
$this->preferredVersion = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue
Block a user