2008-09-05 07:47:08 +02:00
< ? php
/**
2013-09-22 06:44:10 +02:00
* WordPress Filesystem Class for implementing SSH2
2008-09-05 07:47:08 +02:00
*
2008-09-09 05:24:05 +02:00
* To use this class you must follow these steps for PHP 5.2 . 6 +
*
* @ contrib http :// kevin . vanzonneveld . net / techblog / article / make_ssh_connections_with_php / - Installation Notes
*
2009-06-23 23:54:53 +02:00
* Complie libssh2 ( Note : Only 0.14 is officaly working with PHP 5.2 . 6 + right now , But many users have found the latest versions work )
2008-09-09 05:24:05 +02:00
*
* cd / usr / src
* wget http :// surfnet . dl . sourceforge . net / sourceforge / libssh2 / libssh2 - 0.14 . tar . gz
* tar - zxvf libssh2 - 0.14 . tar . gz
* cd libssh2 - 0.14 /
* ./ configure
* make all install
*
2009-06-23 23:54:53 +02:00
* Note : Do not leave the directory yet !
2008-09-09 05:24:05 +02:00
*
* Enter : pecl install - f ssh2
*
* Copy the ssh . so file it creates to your PHP Module Directory .
* Open up your PHP . INI file and look for where extensions are placed .
* Add in your PHP . ini file : extension = ssh2 . so
*
* Restart Apache !
* Check phpinfo () streams to confirm that : ssh2 . shell , ssh2 . exec , ssh2 . tunnel , ssh2 . scp , ssh2 . sftp exist .
*
2009-06-23 23:54:53 +02:00
* Note : as of WordPress 2.8 , This utilises the PHP5 + function 'stream_get_contents'
2008-09-09 05:24:05 +02:00
*
2013-09-22 06:44:10 +02:00
* @ since 2.7 . 0
*
2008-09-05 07:47:08 +02:00
* @ package WordPress
* @ subpackage Filesystem
*/
class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
2008-09-09 05:24:05 +02:00
2009-04-23 01:38:01 +02:00
var $link = false ;
var $sftp_link = false ;
2008-09-11 19:44:43 +02:00
var $keys = false ;
2008-09-05 07:47:08 +02:00
var $errors = array ();
var $options = array ();
2011-04-29 22:05:12 +02:00
function __construct ( $opt = '' ) {
2008-09-05 07:47:08 +02:00
$this -> method = 'ssh2' ;
$this -> errors = new WP_Error ();
2008-09-13 20:06:20 +02:00
//Check if possible to use ssh2 functions.
2008-09-05 07:47:08 +02:00
if ( ! extension_loaded ( 'ssh2' ) ) {
$this -> errors -> add ( 'no_ssh2_ext' , __ ( 'The ssh2 PHP extension is not available' ));
return false ;
}
2009-06-23 23:54:53 +02:00
if ( ! function_exists ( 'stream_get_contents' ) ) {
$this -> errors -> add ( 'ssh2_php_requirement' , __ ( 'The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>' ));
2009-04-23 01:38:01 +02:00
return false ;
}
2008-09-05 07:47:08 +02:00
// Set defaults:
if ( empty ( $opt [ 'port' ]) )
$this -> options [ 'port' ] = 22 ;
else
$this -> options [ 'port' ] = $opt [ 'port' ];
if ( empty ( $opt [ 'hostname' ]) )
$this -> errors -> add ( 'empty_hostname' , __ ( 'SSH2 hostname is required' ));
else
$this -> options [ 'hostname' ] = $opt [ 'hostname' ];
2010-03-19 22:29:21 +01:00
if ( ! empty ( $opt [ 'base' ]) )
2008-09-05 07:47:08 +02:00
$this -> wp_base = $opt [ 'base' ];
// Check if the options provided are OK.
2009-04-23 01:38:01 +02:00
if ( ! empty ( $opt [ 'public_key' ]) && ! empty ( $opt [ 'private_key' ]) ) {
2008-12-09 19:03:31 +01:00
$this -> options [ 'public_key' ] = $opt [ 'public_key' ];
2008-09-11 19:44:43 +02:00
$this -> options [ 'private_key' ] = $opt [ 'private_key' ];
2008-12-09 19:03:31 +01:00
2009-04-23 01:38:01 +02:00
$this -> options [ 'hostkey' ] = array ( 'hostkey' => 'ssh-rsa' );
2008-12-09 19:03:31 +01:00
$this -> keys = true ;
2009-04-23 01:38:01 +02:00
} elseif ( empty ( $opt [ 'username' ]) ) {
$this -> errors -> add ( 'empty_username' , __ ( 'SSH2 username is required' ));
2008-09-11 19:44:43 +02:00
}
2009-04-23 01:38:01 +02:00
if ( ! empty ( $opt [ 'username' ]) )
$this -> options [ 'username' ] = $opt [ 'username' ];
2008-09-11 19:44:43 +02:00
2008-09-13 20:06:20 +02:00
if ( empty ( $opt [ 'password' ]) ) {
2009-06-23 23:54:53 +02:00
if ( ! $this -> keys ) //password can be blank if we are using keys
2008-09-11 19:44:43 +02:00
$this -> errors -> add ( 'empty_password' , __ ( 'SSH2 password is required' ));
2008-09-13 20:06:20 +02:00
} else {
2008-09-05 07:47:08 +02:00
$this -> options [ 'password' ] = $opt [ 'password' ];
2008-09-13 20:06:20 +02:00
}
2008-12-09 19:03:31 +01:00
2008-09-05 07:47:08 +02:00
}
function connect () {
2008-09-13 20:06:20 +02:00
if ( ! $this -> keys ) {
2008-12-09 19:03:31 +01:00
$this -> link = @ ssh2_connect ( $this -> options [ 'hostname' ], $this -> options [ 'port' ]);
2008-09-13 20:06:20 +02:00
} else {
2008-12-09 19:03:31 +01:00
$this -> link = @ ssh2_connect ( $this -> options [ 'hostname' ], $this -> options [ 'port' ], $this -> options [ 'hostkey' ]);
2008-09-13 20:06:20 +02:00
}
2008-12-09 19:03:31 +01:00
2008-09-05 07:47:08 +02:00
if ( ! $this -> link ) {
$this -> errors -> add ( 'connect' , sprintf ( __ ( 'Failed to connect to SSH2 Server %1$s:%2$s' ), $this -> options [ 'hostname' ], $this -> options [ 'port' ]));
return false ;
}
2008-09-11 19:44:43 +02:00
if ( ! $this -> keys ) {
if ( ! @ ssh2_auth_password ( $this -> link , $this -> options [ 'username' ], $this -> options [ 'password' ]) ) {
$this -> errors -> add ( 'auth' , sprintf ( __ ( 'Username/Password incorrect for %s' ), $this -> options [ 'username' ]));
return false ;
}
} else {
if ( ! @ ssh2_auth_pubkey_file ( $this -> link , $this -> options [ 'username' ], $this -> options [ 'public_key' ], $this -> options [ 'private_key' ], $this -> options [ 'password' ] ) ) {
2009-06-14 11:28:29 +02:00
$this -> errors -> add ( 'auth' , sprintf ( __ ( 'Public and Private keys incorrect for %s' ), $this -> options [ 'username' ]));
2008-09-11 19:44:43 +02:00
return false ;
}
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
$this -> sftp_link = ssh2_sftp ( $this -> link );
2008-09-05 07:47:08 +02:00
return true ;
}
2008-09-09 05:24:05 +02:00
2009-04-23 01:38:01 +02:00
function run_command ( $command , $returnbool = false ) {
if ( ! $this -> link )
return false ;
if ( ! ( $stream = ssh2_exec ( $this -> link , $command )) ) {
2008-09-09 05:24:05 +02:00
$this -> errors -> add ( 'command' , sprintf ( __ ( 'Unable to perform command: %s' ), $command ));
} else {
stream_set_blocking ( $stream , true );
2009-08-15 14:01:04 +02:00
stream_set_timeout ( $stream , FS_TIMEOUT );
2009-06-23 23:54:53 +02:00
$data = stream_get_contents ( $stream );
fclose ( $stream );
2009-04-23 01:38:01 +02:00
if ( $returnbool )
2009-06-23 23:54:53 +02:00
return ( $data === false ) ? false : '' != trim ( $data );
2009-04-23 01:38:01 +02:00
else
2008-09-09 05:24:05 +02:00
return $data ;
}
return false ;
2008-09-05 07:47:08 +02:00
}
2013-09-09 04:43:08 +02:00
function get_contents ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return file_get_contents ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function get_contents_array ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return file ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2010-01-14 10:23:53 +01:00
function put_contents ( $file , $contents , $mode = false ) {
2013-09-09 05:05:09 +02:00
$ret = file_put_contents ( 'ssh2.sftp://' . $this -> sftp_link . '/' . ltrim ( $file , '/' ), $contents );
2010-01-14 10:23:53 +01:00
2013-09-09 04:43:08 +02:00
if ( $ret !== strlen ( $contents ) )
return false ;
2010-01-14 10:23:53 +01:00
$this -> chmod ( $file , $mode );
2013-09-09 04:43:08 +02:00
return true ;
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function cwd () {
2009-04-23 01:38:01 +02:00
$cwd = $this -> run_command ( 'pwd' );
2010-01-18 21:34:48 +01:00
if ( $cwd )
2008-09-05 07:47:08 +02:00
$cwd = trailingslashit ( $cwd );
return $cwd ;
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function chdir ( $dir ) {
2009-04-23 01:38:01 +02:00
return $this -> run_command ( 'cd ' . $dir , true );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function chgrp ( $file , $group , $recursive = false ) {
2008-09-09 05:24:05 +02:00
if ( ! $this -> exists ( $file ) )
return false ;
if ( ! $recursive || ! $this -> is_dir ( $file ) )
2013-07-10 06:15:13 +02:00
return $this -> run_command ( sprintf ( 'chgrp %s %s' , escapeshellarg ( $group ), escapeshellarg ( $file )), true );
return $this -> run_command ( sprintf ( 'chgrp -R %s %s' , escapeshellarg ( $group ), escapeshellarg ( $file )), true );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function chmod ( $file , $mode = false , $recursive = false ) {
if ( ! $this -> exists ( $file ) )
return false ;
2009-08-16 10:34:53 +02:00
if ( ! $mode ) {
if ( $this -> is_file ( $file ) )
$mode = FS_CHMOD_FILE ;
elseif ( $this -> is_dir ( $file ) )
$mode = FS_CHMOD_DIR ;
else
2009-09-14 16:03:32 +02:00
return false ;
2009-08-16 10:34:53 +02:00
}
2008-09-09 05:24:05 +02:00
if ( ! $recursive || ! $this -> is_dir ( $file ) )
2009-04-23 01:38:01 +02:00
return $this -> run_command ( sprintf ( 'chmod %o %s' , $mode , escapeshellarg ( $file )), true );
return $this -> run_command ( sprintf ( 'chmod -R %o %s' , $mode , escapeshellarg ( $file )), true );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2013-09-22 06:44:10 +02:00
/**
* Change the ownership of a file / folder .
*
* @ since Unknown
*
* @ param string $file Path to the file .
* @ param mixed $owner A user name or number .
* @ param bool $recursive Optional . If set True changes file owner recursivly . Defaults to False .
* @ return bool Returns true on success or false on failure .
*/
function chown ( $file , $owner , $recursive = false ) {
2008-09-09 05:24:05 +02:00
if ( ! $this -> exists ( $file ) )
return false ;
if ( ! $recursive || ! $this -> is_dir ( $file ) )
2013-07-10 06:15:13 +02:00
return $this -> run_command ( sprintf ( 'chown %s %s' , escapeshellarg ( $owner ), escapeshellarg ( $file )), true );
return $this -> run_command ( sprintf ( 'chown -R %s %s' , escapeshellarg ( $owner ), escapeshellarg ( $file )), true );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function owner ( $file ) {
2009-04-23 01:38:01 +02:00
$owneruid = @ fileowner ( 'ssh2.sftp://' . $this -> sftp_link . '/' . ltrim ( $file , '/' ));
if ( ! $owneruid )
return false ;
if ( ! function_exists ( 'posix_getpwuid' ) )
return $owneruid ;
$ownerarray = posix_getpwuid ( $owneruid );
return $ownerarray [ 'name' ];
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function getchmod ( $file ) {
2014-03-17 21:17:15 +01:00
return substr ( decoct ( @ fileperms ( 'ssh2.sftp://' . $this -> sftp_link . '/' . ltrim ( $file , '/' ) ) ), - 3 );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function group ( $file ) {
2009-04-23 01:38:01 +02:00
$gid = @ filegroup ( 'ssh2.sftp://' . $this -> sftp_link . '/' . ltrim ( $file , '/' ));
if ( ! $gid )
return false ;
if ( ! function_exists ( 'posix_getgrgid' ) )
return $gid ;
$grouparray = posix_getgrgid ( $gid );
return $grouparray [ 'name' ];
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2011-03-22 01:04:15 +01:00
function copy ( $source , $destination , $overwrite = false , $mode = false ) {
2010-01-18 21:34:48 +01:00
if ( ! $overwrite && $this -> exists ( $destination ) )
2008-09-05 07:47:08 +02:00
return false ;
$content = $this -> get_contents ( $source );
2010-01-18 21:34:48 +01:00
if ( false === $content )
2008-09-05 07:47:08 +02:00
return false ;
2011-03-22 01:04:15 +01:00
return $this -> put_contents ( $destination , $content , $mode );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function move ( $source , $destination , $overwrite = false ) {
return @ ssh2_sftp_rename ( $this -> link , $source , $destination );
}
2011-03-22 01:04:15 +01:00
function delete ( $file , $recursive = false , $type = false ) {
if ( 'f' == $type || $this -> is_file ( $file ) )
2008-09-09 05:24:05 +02:00
return ssh2_sftp_unlink ( $this -> sftp_link , $file );
if ( ! $recursive )
return ssh2_sftp_rmdir ( $this -> sftp_link , $file );
2008-09-05 07:47:08 +02:00
$filelist = $this -> dirlist ( $file );
2008-09-09 05:24:05 +02:00
if ( is_array ( $filelist ) ) {
foreach ( $filelist as $filename => $fileinfo ) {
2011-03-22 01:04:15 +01:00
$this -> delete ( $file . '/' . $filename , $recursive , $fileinfo [ 'type' ]);
2008-09-09 05:24:05 +02:00
}
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
return ssh2_sftp_rmdir ( $this -> sftp_link , $file );
2008-09-05 07:47:08 +02:00
}
function exists ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return file_exists ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function is_file ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return is_file ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function is_dir ( $path ) {
2009-04-23 01:38:01 +02:00
$path = ltrim ( $path , '/' );
2009-06-23 23:54:53 +02:00
return is_dir ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $path );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function is_readable ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return is_readable ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function is_writable ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return is_writable ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function atime ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return fileatime ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function mtime ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return filemtime ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function size ( $file ) {
2009-04-23 01:38:01 +02:00
$file = ltrim ( $file , '/' );
2009-06-23 23:54:53 +02:00
return filesize ( 'ssh2.sftp://' . $this -> sftp_link . '/' . $file );
2008-09-05 07:47:08 +02:00
}
2008-09-09 05:24:05 +02:00
2008-09-05 07:47:08 +02:00
function touch ( $file , $time = 0 , $atime = 0 ) {
2011-09-03 16:18:10 +02:00
//Not implemented.
2008-09-05 07:47:08 +02:00
}
2008-12-09 19:03:31 +01:00
2009-08-16 10:34:53 +02:00
function mkdir ( $path , $chmod = false , $chown = false , $chgrp = false ) {
2008-09-13 20:06:20 +02:00
$path = untrailingslashit ( $path );
2011-10-13 12:43:38 +02:00
if ( empty ( $path ) )
return false ;
2009-08-16 10:34:53 +02:00
if ( ! $chmod )
$chmod = FS_CHMOD_DIR ;
2009-04-23 01:38:01 +02:00
if ( ! ssh2_sftp_mkdir ( $this -> sftp_link , $path , $chmod , true ) )
2008-09-05 07:47:08 +02:00
return false ;
2009-04-23 01:38:01 +02:00
if ( $chown )
2008-09-05 07:47:08 +02:00
$this -> chown ( $path , $chown );
2009-04-23 01:38:01 +02:00
if ( $chgrp )
2008-09-05 07:47:08 +02:00
$this -> chgrp ( $path , $chgrp );
return true ;
}
2008-09-09 05:24:05 +02:00
function rmdir ( $path , $recursive = false ) {
return $this -> delete ( $path , $recursive );
2008-09-05 07:47:08 +02:00
}
2009-09-15 04:21:00 +02:00
function dirlist ( $path , $include_hidden = true , $recursive = false ) {
2009-04-23 01:38:01 +02:00
if ( $this -> is_file ( $path ) ) {
2009-09-15 04:21:00 +02:00
$limit_file = basename ( $path );
2009-04-23 01:38:01 +02:00
$path = dirname ( $path );
2008-09-05 07:47:08 +02:00
} else {
2009-09-15 04:21:00 +02:00
$limit_file = false ;
2008-09-05 07:47:08 +02:00
}
2009-09-15 04:21:00 +02:00
2009-04-23 01:38:01 +02:00
if ( ! $this -> is_dir ( $path ) )
2008-09-05 07:47:08 +02:00
return false ;
2009-04-23 01:38:01 +02:00
$ret = array ();
$dir = @ dir ( 'ssh2.sftp://' . $this -> sftp_link . '/' . ltrim ( $path , '/' ) );
2009-09-15 04:21:00 +02:00
2009-04-23 01:38:01 +02:00
if ( ! $dir )
return false ;
2009-09-15 04:21:00 +02:00
2009-04-23 01:38:01 +02:00
while ( false !== ( $entry = $dir -> read ()) ) {
$struc = array ();
$struc [ 'name' ] = $entry ;
2008-09-09 05:24:05 +02:00
2009-04-23 01:38:01 +02:00
if ( '.' == $struc [ 'name' ] || '..' == $struc [ 'name' ] )
continue ; //Do not care about these folders.
2009-09-15 04:21:00 +02:00
if ( ! $include_hidden && '.' == $struc [ 'name' ][ 0 ] )
2008-09-05 07:47:08 +02:00
continue ;
2009-09-15 04:21:00 +02:00
if ( $limit_file && $struc [ 'name' ] != $limit_file )
2008-09-05 07:47:08 +02:00
continue ;
2009-04-23 01:38:01 +02:00
$struc [ 'perms' ] = $this -> gethchmod ( $path . '/' . $entry );
$struc [ 'permsn' ] = $this -> getnumchmodfromh ( $struc [ 'perms' ]);
$struc [ 'number' ] = false ;
$struc [ 'owner' ] = $this -> owner ( $path . '/' . $entry );
$struc [ 'group' ] = $this -> group ( $path . '/' . $entry );
$struc [ 'size' ] = $this -> size ( $path . '/' . $entry );
$struc [ 'lastmodunix' ] = $this -> mtime ( $path . '/' . $entry );
$struc [ 'lastmod' ] = date ( 'M j' , $struc [ 'lastmodunix' ]);
$struc [ 'time' ] = date ( 'h:i:s' , $struc [ 'lastmodunix' ]);
$struc [ 'type' ] = $this -> is_dir ( $path . '/' . $entry ) ? 'd' : 'f' ;
2008-09-05 07:47:08 +02:00
if ( 'd' == $struc [ 'type' ] ) {
2009-04-23 01:38:01 +02:00
if ( $recursive )
2009-09-15 04:21:00 +02:00
$struc [ 'files' ] = $this -> dirlist ( $path . '/' . $struc [ 'name' ], $include_hidden , $recursive );
2009-04-23 01:38:01 +02:00
else
$struc [ 'files' ] = array ();
2008-09-05 07:47:08 +02:00
}
2009-04-23 01:38:01 +02:00
$ret [ $struc [ 'name' ] ] = $struc ;
2008-09-05 07:47:08 +02:00
}
2009-04-23 01:38:01 +02:00
$dir -> close ();
unset ( $dir );
2008-09-05 07:47:08 +02:00
return $ret ;
}
2009-06-14 11:28:29 +02:00
}