PageRenderTime 266ms CodeModel.GetById 80ms app.highlight 62ms RepoModel.GetById 119ms app.codeStats 1ms

/wordpress3.4.2/wp-admin/includes/class-wp-filesystem-ssh2.php

https://bitbucket.org/ch3tag/mothers
PHP | 386 lines | 279 code | 63 blank | 44 comment | 70 complexity | 3de1191f97d437526cc421829c544c2e MD5 | raw file
  1<?php
  2/**
  3 * WordPress SSH2 Filesystem.
  4 *
  5 * @package WordPress
  6 * @subpackage Filesystem
  7 */
  8
  9/**
 10 * WordPress Filesystem Class for implementing SSH2.
 11 *
 12 * To use this class you must follow these steps for PHP 5.2.6+
 13 *
 14 * @contrib http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/ - Installation Notes
 15 *
 16 * 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)
 17 *
 18 * cd /usr/src
 19 * wget http://surfnet.dl.sourceforge.net/sourceforge/libssh2/libssh2-0.14.tar.gz
 20 * tar -zxvf libssh2-0.14.tar.gz
 21 * cd libssh2-0.14/
 22 * ./configure
 23 * make all install
 24 *
 25 * Note: Do not leave the directory yet!
 26 *
 27 * Enter: pecl install -f ssh2
 28 *
 29 * Copy the ssh.so file it creates to your PHP Module Directory.
 30 * Open up your PHP.INI file and look for where extensions are placed.
 31 * Add in your PHP.ini file: extension=ssh2.so
 32 *
 33 * Restart Apache!
 34 * Check phpinfo() streams to confirm that: ssh2.shell, ssh2.exec, ssh2.tunnel, ssh2.scp, ssh2.sftp  exist.
 35 *
 36 * Note: as of WordPress 2.8, This utilises the PHP5+ function 'stream_get_contents'
 37 *
 38 * @since 2.7
 39 * @package WordPress
 40 * @subpackage Filesystem
 41 * @uses WP_Filesystem_Base Extends class
 42 */
 43class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
 44
 45	var $link = false;
 46	var $sftp_link = false;
 47	var $keys = false;
 48	var $errors = array();
 49	var $options = array();
 50
 51	function __construct($opt='') {
 52		$this->method = 'ssh2';
 53		$this->errors = new WP_Error();
 54
 55		//Check if possible to use ssh2 functions.
 56		if ( ! extension_loaded('ssh2') ) {
 57			$this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available'));
 58			return false;
 59		}
 60		if ( !function_exists('stream_get_contents') ) {
 61			$this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>'));
 62			return false;
 63		}
 64
 65		// Set defaults:
 66		if ( empty($opt['port']) )
 67			$this->options['port'] = 22;
 68		else
 69			$this->options['port'] = $opt['port'];
 70
 71		if ( empty($opt['hostname']) )
 72			$this->errors->add('empty_hostname', __('SSH2 hostname is required'));
 73		else
 74			$this->options['hostname'] = $opt['hostname'];
 75
 76		if ( ! empty($opt['base']) )
 77			$this->wp_base = $opt['base'];
 78
 79		// Check if the options provided are OK.
 80		if ( !empty ($opt['public_key']) && !empty ($opt['private_key']) ) {
 81			$this->options['public_key'] = $opt['public_key'];
 82			$this->options['private_key'] = $opt['private_key'];
 83
 84			$this->options['hostkey'] = array('hostkey' => 'ssh-rsa');
 85
 86			$this->keys = true;
 87		} elseif ( empty ($opt['username']) ) {
 88			$this->errors->add('empty_username', __('SSH2 username is required'));
 89		}
 90
 91		if ( !empty($opt['username']) )
 92			$this->options['username'] = $opt['username'];
 93
 94		if ( empty ($opt['password']) ) {
 95			if ( !$this->keys )	//password can be blank if we are using keys
 96				$this->errors->add('empty_password', __('SSH2 password is required'));
 97		} else {
 98			$this->options['password'] = $opt['password'];
 99		}
100
101	}
102
103	function connect() {
104		if ( ! $this->keys ) {
105			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
106		} else {
107			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']);
108		}
109
110		if ( ! $this->link ) {
111			$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
112			return false;
113		}
114
115		if ( !$this->keys ) {
116			if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
117				$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
118				return false;
119			}
120		} else {
121			if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) {
122				$this->errors->add('auth', sprintf(__('Public and Private keys incorrect for %s'), $this->options['username']));
123				return false;
124			}
125		}
126
127		$this->sftp_link = ssh2_sftp($this->link);
128
129		return true;
130	}
131
132	function run_command( $command, $returnbool = false) {
133
134		if ( ! $this->link )
135			return false;
136
137		if ( ! ($stream = ssh2_exec($this->link, $command)) ) {
138			$this->errors->add('command', sprintf(__('Unable to perform command: %s'), $command));
139		} else {
140			stream_set_blocking( $stream, true );
141			stream_set_timeout( $stream, FS_TIMEOUT );
142			$data = stream_get_contents( $stream );
143			fclose( $stream );
144
145			if ( $returnbool )
146				return ( $data === false ) ? false : '' != trim($data);
147			else
148				return $data;
149		}
150		return false;
151	}
152
153	function get_contents($file, $type = '', $resumepos = 0 ) {
154		$file = ltrim($file, '/');
155		return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file);
156	}
157
158	function get_contents_array($file) {
159		$file = ltrim($file, '/');
160		return file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
161	}
162
163	function put_contents($file, $contents, $mode = false ) {
164		$file = ltrim($file, '/');
165		$ret = file_put_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file, $contents);
166
167		$this->chmod($file, $mode);
168
169		return false !== $ret;
170	}
171
172	function cwd() {
173		$cwd = $this->run_command('pwd');
174		if ( $cwd )
175			$cwd = trailingslashit($cwd);
176		return $cwd;
177	}
178
179	function chdir($dir) {
180		return $this->run_command('cd ' . $dir, true);
181	}
182
183	function chgrp($file, $group, $recursive = false ) {
184		if ( ! $this->exists($file) )
185			return false;
186		if ( ! $recursive || ! $this->is_dir($file) )
187			return $this->run_command(sprintf('chgrp %o %s', $mode, escapeshellarg($file)), true);
188		return $this->run_command(sprintf('chgrp -R %o %s', $mode, escapeshellarg($file)), true);
189	}
190
191	function chmod($file, $mode = false, $recursive = false) {
192		if ( ! $this->exists($file) )
193			return false;
194
195		if ( ! $mode ) {
196			if ( $this->is_file($file) )
197				$mode = FS_CHMOD_FILE;
198			elseif ( $this->is_dir($file) )
199				$mode = FS_CHMOD_DIR;
200			else
201				return false;
202		}
203
204		if ( ! $recursive || ! $this->is_dir($file) )
205			return $this->run_command(sprintf('chmod %o %s', $mode, escapeshellarg($file)), true);
206		return $this->run_command(sprintf('chmod -R %o %s', $mode, escapeshellarg($file)), true);
207	}
208
209	function chown($file, $owner, $recursive = false ) {
210		if ( ! $this->exists($file) )
211			return false;
212		if ( ! $recursive || ! $this->is_dir($file) )
213			return $this->run_command(sprintf('chown %o %s', $mode, escapeshellarg($file)), true);
214		return $this->run_command(sprintf('chown -R %o %s', $mode, escapeshellarg($file)), true);
215	}
216
217	function owner($file) {
218		$owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
219		if ( ! $owneruid )
220			return false;
221		if ( ! function_exists('posix_getpwuid') )
222			return $owneruid;
223		$ownerarray = posix_getpwuid($owneruid);
224		return $ownerarray['name'];
225	}
226
227	function getchmod($file) {
228		return substr(decoct(@fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/') )),3);
229	}
230
231	function group($file) {
232		$gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
233		if ( ! $gid )
234			return false;
235		if ( ! function_exists('posix_getgrgid') )
236			return $gid;
237		$grouparray = posix_getgrgid($gid);
238		return $grouparray['name'];
239	}
240
241	function copy($source, $destination, $overwrite = false, $mode = false) {
242		if ( ! $overwrite && $this->exists($destination) )
243			return false;
244		$content = $this->get_contents($source);
245		if ( false === $content)
246			return false;
247		return $this->put_contents($destination, $content, $mode);
248	}
249
250	function move($source, $destination, $overwrite = false) {
251		return @ssh2_sftp_rename($this->link, $source, $destination);
252	}
253
254	function delete($file, $recursive = false, $type = false) {
255		if ( 'f' == $type || $this->is_file($file) )
256			return ssh2_sftp_unlink($this->sftp_link, $file);
257		if ( ! $recursive )
258			 return ssh2_sftp_rmdir($this->sftp_link, $file);
259		$filelist = $this->dirlist($file);
260		if ( is_array($filelist) ) {
261			foreach ( $filelist as $filename => $fileinfo) {
262				$this->delete($file . '/' . $filename, $recursive, $fileinfo['type']);
263			}
264		}
265		return ssh2_sftp_rmdir($this->sftp_link, $file);
266	}
267
268	function exists($file) {
269		$file = ltrim($file, '/');
270		return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file);
271	}
272
273	function is_file($file) {
274		$file = ltrim($file, '/');
275		return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
276	}
277
278	function is_dir($path) {
279		$path = ltrim($path, '/');
280		return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path);
281	}
282
283	function is_readable($file) {
284		$file = ltrim($file, '/');
285		return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
286	}
287
288	function is_writable($file) {
289		$file = ltrim($file, '/');
290		return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
291	}
292
293	function atime($file) {
294		$file = ltrim($file, '/');
295		return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
296	}
297
298	function mtime($file) {
299		$file = ltrim($file, '/');
300		return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
301	}
302
303	function size($file) {
304		$file = ltrim($file, '/');
305		return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file);
306	}
307
308	function touch($file, $time = 0, $atime = 0) {
309		//Not implemented.
310	}
311
312	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
313		$path = untrailingslashit($path);
314		if ( empty($path) )
315			return false;
316
317		if ( ! $chmod )
318			$chmod = FS_CHMOD_DIR;
319		if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
320			return false;
321		if ( $chown )
322			$this->chown($path, $chown);
323		if ( $chgrp )
324			$this->chgrp($path, $chgrp);
325		return true;
326	}
327
328	function rmdir($path, $recursive = false) {
329		return $this->delete($path, $recursive);
330	}
331
332	function dirlist($path, $include_hidden = true, $recursive = false) {
333		if ( $this->is_file($path) ) {
334			$limit_file = basename($path);
335			$path = dirname($path);
336		} else {
337			$limit_file = false;
338		}
339
340		if ( ! $this->is_dir($path) )
341			return false;
342
343		$ret = array();
344		$dir = @dir('ssh2.sftp://' . $this->sftp_link .'/' . ltrim($path, '/') );
345
346		if ( ! $dir )
347			return false;
348
349		while (false !== ($entry = $dir->read()) ) {
350			$struc = array();
351			$struc['name'] = $entry;
352
353			if ( '.' == $struc['name'] || '..' == $struc['name'] )
354				continue; //Do not care about these folders.
355
356			if ( ! $include_hidden && '.' == $struc['name'][0] )
357				continue;
358
359			if ( $limit_file && $struc['name'] != $limit_file )
360				continue;
361
362			$struc['perms'] 	= $this->gethchmod($path.'/'.$entry);
363			$struc['permsn']	= $this->getnumchmodfromh($struc['perms']);
364			$struc['number'] 	= false;
365			$struc['owner']    	= $this->owner($path.'/'.$entry);
366			$struc['group']    	= $this->group($path.'/'.$entry);
367			$struc['size']    	= $this->size($path.'/'.$entry);
368			$struc['lastmodunix']= $this->mtime($path.'/'.$entry);
369			$struc['lastmod']   = date('M j',$struc['lastmodunix']);
370			$struc['time']    	= date('h:i:s',$struc['lastmodunix']);
371			$struc['type']		= $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
372
373			if ( 'd' == $struc['type'] ) {
374				if ( $recursive )
375					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
376				else
377					$struc['files'] = array();
378			}
379
380			$ret[ $struc['name'] ] = $struc;
381		}
382		$dir->close();
383		unset($dir);
384		return $ret;
385	}
386}