From c4723fc3f21c307411993ad75957f8d6823a3ef4 Mon Sep 17 00:00:00 2001 From: "Andreas Burchert (scarya)" Date: Sat, 16 Oct 2010 23:31:38 +0000 Subject: [PATCH] - added FroxlorSshTransport for upcoming multiserver-support --- .../class.FroxlorSshTransport.php | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 lib/classes/sshtransport/class.FroxlorSshTransport.php diff --git a/lib/classes/sshtransport/class.FroxlorSshTransport.php b/lib/classes/sshtransport/class.FroxlorSshTransport.php new file mode 100644 index 00000000..7f2fcad2 --- /dev/null +++ b/lib/classes/sshtransport/class.FroxlorSshTransport.php @@ -0,0 +1,267 @@ + + * @copyright 2010 the authors + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @version SVN: $Id: class.FroxlorModule.php 1167 2010-06-22 11:46:34Z d00p $ + * @link http://www.froxlor.org/ + */ + +/** + * Class FroxlorSshTransport + * + * This class handles remote server related stuff. + * + * @category FroxlorCore + * @package Classes + * @subpackage System + * @author Froxlor Team + * @copyright 2010 the authors + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @link http://www.froxlor.org/ + */ +class FroxlorSshTransport +{ + /** + * Clas object. + * + * @var FroxlorSshTransport + */ + private static $_instance = null; + + /** + * Contains the connection handle. + * + * @var resource + */ + private $_connection = null; + + /** + * Contains all information for the ssh connection. + * + * @var array + */ + private $_settings = array(); + + /** + * Contains the shell resource. + * + * @var resource + */ + private $_shell = null; + + /** + * Constructor (Singleton) + * + * @param array $settings contains an array of settings for the connection + * + * @return FroxlorSshTransport + * + * @throws Exception if the connection could not be established + */ + private function __construct($settings) + { + // settings + $this->_settings = $settings; + // try to connect + $this->_connect(); + + // get a shell stream + $this->_shell = $this->_getShell(); + } + + /** + * Constructor for publickey auth + * + * @param string $ip ip toremote server + * @param string $port remote port + * @param string $username ssh username + * @param string $pubkeyfile path to pubkeyfile + * @param string $privkeyfile path to privatekeyfile + * @param string $passphrase passphrase + * + * @return FroxlorSshTransport + */ + public static function usePublicKey($ip, $port, $username, $pubkeyfile, $privkeyfile , $passphrase) + { + $settings = array( + 'ip' => $ip, + 'port' => $port, + 'username' => $username, + 'pubkeyfile' => $pubkeyfile, + 'privkeyfile' => $privkeyfile, + 'passphrase' => $passphrase + ); + + if (is_null(self::$_instance)) { + self::$_instance = new FroxlorSshTransport($settings); + } + + return self::$_instance; + } + + /** + * + * + * @param string $ip ip toremote server + * @param string $port remote port + * @param string $username ssh username + * @param string $password ssh password + * + * @return FroxlorSshTransport + */ + public static function usePlainPassword($ip, $port, $username, $password) + { + $settings = array( + 'ip' => $ip, + 'port' => $port, + 'username' => $username, + 'password' => $password + ); + + if (is_null(self::$_instance)) { + self::$_instance = new FroxlorSshTransport($settings); + } + + return self::$_instance; + } + + /** + * Send a command to the shell session. + * + * @param string $cmd command to send (without EOL) + */ + public function sendCmd($cmd) + { + // writes the command to the shell + fwrite($this->_shell, $cmd.PHP_EOL); + } + + /** + * Sends a file to the remote server. + * + * @param string $localFile path to the local file + * @param string $remoteFile remote file path + * @param string $chmod file rights (default: 0644) + * + * @return boolean + */ + public function sendFile($localFile, $remoteFile, $chmod = 0644) + { + // check if file exists + if (@!is_readable($localFile)) { + return false; + } + + // send file + if (ssh2_scp_send($this->_connection, $localFile, $remoteFile, $chmod)) { + return true; + } else { + return false; + } + } + + /** + * This reads all available output. + * + * @return array + */ + public function readAll() + { + if (is_null($this->_shell)) { + return array(); + } + + $output = array(); + + while($line = fgets($this->_shell)) { + $output[] = $line; + } + + return $output; + } + + /** + * Clean up. + */ + public function close() + { + $this->_shell = null; + $this->_settings = null; + $this->_connection = null; + $this->_instance = null; + } + + /** + * This function connects to the remote server. + * + * @return void + */ + private function _connect() + { + $callbacks = array('disconnect' => array('FroxlorSshTransport', 'disconnected')); + + if ($this->_settings['pubkeyfile']) { + // pubkey authentication + $this->_connection = ssh2_connect($this->_settings['ip'], $this->_settings['port'], array('hostkey'=>'ssh-rsa'), $callbacks); + $success = ssh2_auth_pubkey_file($this->_connection, $this->_settings['username'], $pubkeyfile, $privkeyfile, $passphrase); + } else { + // plain password authentication + $this->_connection = ssh2_connect($this->_settings['ip'], $this->_settings['port'], array(), $callbacks); + $success = ssh2_auth_password($this->_connection, $this->_settings['username'], $this->_settings['password']); + } + + // check connection + if (!$success) { + // TODO change this to an Exception for froxlor 1.0 + throw new Exception("Connection to ssh could not be established!"); + } + } + + /** + * Returns a shell. + * + * @return resource + */ + private function _getShell() + { + return ssh2_shell($this->_connection, 'vt102', null, 80, 24, SSH2_TERM_UNIT_CHARS); + } + + /** + * Callback function if the connection disconnects. + * + * @param string $reason reason + * @param string $message message + * @param string $language language + * + * @return void + */ + public static function disconnected($reason, $message, $language) + { + // try reconnecting + try{ + self::$_instance->_connect(); + } catch (Exception $e) { + die("Connection lost and could not re-established! \n".$reason."\n".$message."\n".$language."\n".$e->getMessage()); + } + } +} +?> \ No newline at end of file