João Batista Neto 448 Denunciar post Postado Março 12, 2010 Um dos padrões de projeto mais legais é o State, com ele, um objeto pode mudar seu comportamento em tempo de execução dependendo do estado corrente e cada implementação de estado preocupa-se apenas com o que deve fazer, deixando assim um código limpo e totalmente reutilizável. Cada ConcreteState implementa um comportamento específico permitindo, dessa forma, que novos comportamentos sejam anexados.No caso de uma conexão SSH:Nosso contexto inicia-se como SSHStateClosed, assim que executamos o método open() nosso estado passa a ser SSHStateEstabilished e podemos verificar a assinatura do host e autenticar; Assim que autenticado o estado passa à SSHStateListen para que possamos enviar comandos ao servidor remoto.Como uma autenticação pode ser de várias formas, deixamos a implementação separada em um objeto específico, dessa forma, podemos autenticar com usuário e senha ou, se for o caso, utilizando certificados digitais (entre outras).Um comando deveria ser implementado da mesma forma, porém, para simplificar as coisas, vamos trabalhar com strings mesmo:com/ssh/auth/SSHAuthenticatePassword.php <?php /** * @author João Batista Neto * @package ssh * @category ssh, state */ namespace comsshauth; /** * @see ISSHAuthentication */ use comsshinterfacesISSHAuthentication; /** * Implementa uma autenticação utilizando nome de usuário e senha * @author João Batista Neto * @final * @package ssh * @category ssh, state, authentication */ final class SSHAuthenticatePassword implements ISSHAuthentication { /** * @var string */ private $user; /** * @var string */ private $pswd; /** * Constroi o objeto de autenticação * @param string $user * @param string $pswd */ public function __construct( $user , $pswd ){ $this->user =& $user; $this->pswd =& $pswd; } /** * Efetua a autenticação * @param resource $resource * @throws InvalidArgumentException se o recurso não for válido */ public function authenticate( &$resource ){ if ( is_resource( $resource ) ){ return ssh2_auth_password( $resource , $this->user , $this->pswd ); } else { throw new InvalidArgumentException( 'Recurso inválido.' ); } return false; } /** * Recupera o nome do usuário * @return string */ public function getUser(){ return $this->user; } } com/ssh/interfaces/AbstractSSHState.php <?php /** * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ namespace comsshinterfaces; /** * Interface para um estado de conexão * @abstract * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ abstract class AbstractSSHState implements ISSHState { /** * @var resource */ protected $resource; /** * Autentica o usuário * @param ISSHAuthentication $auth * @param ISSHConnection $context * @return boolean * @throws BadMethodCallException se o estado não implementar o método authenticate */ public function authenticate( ISSHAuthentication $auth , ISSHConnection $context ){ throw new BadMethodCallException( sprintf( '%s não implementa o método %s' , get_class( $this ) , __METHOD__ ) ); } /** * Executa um comando no servidor remoto * @param string $command * @param ISSHConnection $context * @return boolean * @throws BadMethodCallException se o estado não implementar o método execute */ public function execute( $command , ISSHConnection $context ){ throw new BadMethodCallException( sprintf( '%s não implementa o método %s' , get_class( $this ) , __METHOD__ ) ); } /** * Recupera a fingerprint do servidor * @param ISSHConnection $context * @return string * @throws BadMethodCallException se o estado não implementar o método execute */ public function getFingerprint( ISSHConnection $context ){ throw new BadMethodCallException( sprintf( '%s não implementa o método %s' , get_class( $this ) , __METHOD__ ) ); } /** * Abre uma nova conexão * @param string $host * @param integer $port * @param ISSHConnection $context * @return boolean * @throws BadMethodCallException se o estado não implementar o método open */ public function open( $host , $port = 22 , ISSHConnection $context ){ throw new BadMethodCallException( sprintf( '%s não implementa o método %s' , get_class( $this ) , __METHOD__ ) ); } /** * Define o recurso da conexão * @param resource $resource * @throws InvalidArgumentException se o recurso não for válido */ public function setResource( &$resource ){ if ( !is_resource( $resource ) ){ throw new InvalidArgumentException( 'Recurso inválido.' ); } else { $this->resource =& $resource; } } } com/ssh/interfaces/ISSHAuthentication.php <?php /** * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ namespace comsshinterfaces; /** * Interface para autenticação SSH * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ interface ISSHAuthentication { /** * Efetua a autenticação do usuário * @param resource $resource */ public function authenticate( &$resource ); /** * Recupera o nome do usuário * @return string */ public function getUser(); } com/ssh/interfaces/ISSHConnection.php <?php /** * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ namespace comsshinterfaces; /** * Interface para uma conexão SSH * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ interface ISSHConnection { /** * Autentica um usuário * @param ISSHAuthentication $auth * @return boolean */ public function authenticate( ISSHAuthentication $auth ); /** * Executa um comando no servidor remoto * @param string $command * @return boolean */ public function execute( $command ); /** * Recupera a fingerprint do servidor * @return string */ public function getFingerprint(); /** * Abre uma nova conexão * @param stirng $host * @param integer $port * @return boolean */ public function open( $host , $port ); /** * Modifica o estado da conexão * @param ISSHState $state */ public function changeState( ISSHState $state ); } com/ssh/interfaces/ISSHState.php <?php /** * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ namespace comsshinterfaces; /** * Interface para um estado de conexão * @author João Batista Neto * @package ssh * @subpackage interfaces * @category ssh, state */ interface ISSHState { /** * Autentica o usuário * @param ISSHAuthentication $auth * @param ISSHConnection $context */ public function authenticate( ISSHAuthentication $auth , ISSHConnection $context ); /** * Executa um comando no servidor remoto * @param string $command * @param ISSHConnection $context */ public function execute( $command , ISSHConnection $context ); /** * Recupera a fingerprint do servidor * @param ISSHConnection $context * @return string */ public function getFingerprint( ISSHConnection $context ); /** * Abre uma nova conexão * @param string $host * @param integer $port * @param ISSHConnection $context */ public function open( $host , $port = 22 , ISSHConnection $context ); /** * Define o recurso da conexão * @param resource $resource */ public function setResource( &$resource ); } com/ssh/state/SSHStateClosed.php <?php /** * @author João Batista Neto * @package ssh * @category ssh, state */ namespace comsshstate; /** * @see AbstractSSHState */ use comsshinterfacesAbstractSSHState; /** * @see ISSHConnection */ use comsshinterfacesISSHConnection; /** * Implementa o estado para uma conexão fechada * @author João Batista Neto * @final * @package ssh * @category ssh, state */ final class SSHStateClosed extends AbstractSSHState { /** * @staticvar * @var ISSHConnection */ static private $context; /** * Abre uma nova conexão * @param string $host * @param integer $port * @param ISSHConnection $context * @return boolean * @throws RuntimeException se não for possível estabelecer a conexão * @uses SSHStateEstabilished */ public function open( $host , $port = 22 , ISSHConnection $context ){ $resource = ssh2_connect( $host , $port , array( 'disconnect' => array( 'SSHStateClosed' , 'disconnect' ) ) ); if ( !is_resource( $resource ) ){ throw new RuntimeException( 'Não foi possível estabelecer a conexão.' ); } else { $estabilished = new SSHStateEstabilished(); $estabilished->setResource( $resource ); self::$context =& $context; self::$context->changeState( $estabilished ); } return true; } /** * Muda o estado da conexão para SSHStateClosed caso o servidor envie um disconnect * @static */ static public function disconnect(){ self::$context->changeState( new SSHStateClosed() ); } } com/ssh/state/SSHStateEstabilished.php <?php /** * @author João Batista Neto * @package ssh * @category ssh, state */ namespace comsshstate; /** * @see AbstractSSHState */ use comsshinterfacesAbstractSSHState; /** * @see ISSHConnection */ use comsshinterfacesISSHConnection; /** * @see ISSHAuthentication */ use comsshinterfacesISSHAuthentication; /** * Implementa o estado para uma conexão estabelecida * @author João Batista Neto * @final * @package ssh * @category ssh, state */ final class SSHStateEstabilished extends AbstractSSHState { /** * Efetua a autenticação do usuário * @param ISSHAuthentication $auth * @param ISSHConnection $context * @return boolean * @throws RuntimeException se não for possível autenticar o usuário * @uses SSHStateAuthenticated */ public function authenticate( ISSHAuthentication $auth , ISSHConnection $context ){ if ( !$auth->authenticate( $this->resource ) ){ throw new RuntimeException( sprintf( 'Não foi possível autenticar o usuário %s.' , $auth->getUser() ) ); } else { $authenticated = new SSHStateListen(); $authenticated->setResource( $this->resource ); $context->changeState( $authenticated ); } return true; } /** * Recupera o hash da chave do servidor da conexão ativa * @return string * @throws LogicException se o estado não implementar o método execute */ public function getFingerprint( ISSHConnection $context ){ return ssh2_fingerprint( $this->resource , SSH2_FINGERPRINT_MD5 | SSH2_FINGERPRINT_HEX ); } } com/ssh/state/SSHStateListen.php <?php /** * @author João Batista Neto * @package ssh * @category ssh, state */ namespace comsshstate; /** * @see AbstractSSHState */ use comsshinterfacesAbstractSSHState; /** * @see ISSHConnection */ use comsshinterfacesISSHConnection; /** * Implementa o estado para uma conexão autenticada * @author João Batista Neto * @final * @package ssh * @category ssh, state */ final class SSHStateListen extends AbstractSSHState { /** * @var resource */ private $shell; /** * Executa um comando no servidor remoto * @param string $command * @param ISSHConnection $context * @return string A saída do servidor remoto * @throws RuntimeException se não for possível executar o comando */ public function execute( $command , ISSHConnection $context ){ $ret = null; $stream = ssh2_exec( $this->resource , $command ); if ( is_resource( $stream ) ){ stream_set_blocking( $stream , true ); while ( ( $line = fgets( $stream , 4096 ) ) !== false ){ $ret .= $line; } } else { throw new RuntimeException( 'Não foi possível executar o comando.' ); } return $ret; } } com/ssh/SSHConnection.php <?php /** * @author João Batista Neto * @package ssh * @category ssh, state */ namespace comssh; /** * @see ISSHConnection */ use comsshinterfacesISSHConnection; /** * @see ISSHAuthentication */ use comsshinterfacesISSHAuthentication; /** * @see ISSHState */ use comsshinterfacesISSHState; /** * @see SSHStateClosed */ use comsshstateSSHStateClosed; /** * Implementa uma conexão com um servidor remoto via SSH * @author João Batista Neto * @final * @package ssh * @category ssh, state */ class SSHConnection implements ISSHConnection { /** * @var ISSHState */ private $state; /** * Cria o objeto de conexão */ public function __construct(){ $this->state = new SSHStateClosed(); } /** * Faz a autenticação no servidor * @param ISSHAuthentication $auth * @return boolean */ public function authenticate( ISSHAuthentication $auth ){ return $this->state->authenticate( $auth , $this ); } /** * Executa um comando no servidor * @param string $command * @return boolean */ public function execute( $command ){ return $this->state->execute( $command , $this ); } /** * Recupera a fingerprint do servidor * @return string */ public function getFingerprint(){ return $this->state->getFingerprint( $this ); } /** * Abre uma conexão com um servidor remoto * @param string $host * @param integer $port * @return boolean */ public function open( $host , $port = 22 ){ return $this->state->open( $host , $port , $this ); } /** * Modifica o estado da conexão * @param ISSHState $state */ public function changeState( ISSHState $state ){ $this->state =& $state; } } Agora, para conectar em um servidor remoto via PHP é simples: <?php use comsshSSHConnection; use comsshauthSSHAuthenticatePassword; $teste = new SSHConnection(); $teste->open( '127.0.0.1' ); $teste->authenticate( new SSHAuthenticatePassword( 'usuario' , 'senha' ) ); echo $teste->execute( 'ls -l /var/www/html/xxx/com/ssh' ); No meu caso, a saída foi: total 16drwxr-xr-x. 3 neto apache 4096 Mar 11 18:18 authdrwxr-xr-x. 3 neto apache 4096 Mar 11 18:18 interfaces-rw-r--r--. 1 neto apache 1681 Mar 11 18:17 SSHConnection.phpdrwxr-xr-x. 3 neto apache 4096 Mar 12 06:35 state Compartilhar este post Link para o post Compartilhar em outros sites
h4v3st 1 Denunciar post Postado Março 12, 2010 Excelente trabalho João, meus parabens! :) Compartilhar este post Link para o post Compartilhar em outros sites
Matias Rezende 50 Denunciar post Postado Março 12, 2010 Muito bom. O mestre dos padrões de projeto. http://forum.imasters.com.br/public/style_emoticons/default/joia.gif Carlos Eduardo Compartilhar este post Link para o post Compartilhar em outros sites
lucaswxp 22 Denunciar post Postado Março 12, 2010 Parabéns. O mestre dos padrões de projeto.² :) Compartilhar este post Link para o post Compartilhar em outros sites
Will Fernando 2 Denunciar post Postado Março 15, 2010 Parabéns. O mestre dos padrões de projeto.[3] *Imagem: João pensando no proximo artigo Compartilhar este post Link para o post Compartilhar em outros sites
xamaee 0 Denunciar post Postado Abril 27, 2010 to com um problema, copiei todos arquivos mas to tendo um erro! o arquivo que roda o comando ssh é o test.php todos arquivos e pasta estao com chmod 777 e o php é 5.3.2 Fatal error: Class 'com\ssh\SSHConnection' not found in /var/www/lighttpd/ssh/test.php on line 5 4 ./php.php 4 ./com/ssh/auth/SSHAuthenticatePassword.php 8 ./com/ssh/auth 4 ./com/ssh/interfaces/ISSHAuthentication.php 4 ./com/ssh/interfaces/AbstractSSHState.php 4 ./com/ssh/interfaces/ISSHState.php 16 ./com/ssh/interfaces 4 ./com/ssh/SSHConnection.php 4 ./com/ssh/state/SSHStateClosed.php 4 ./com/ssh/state/SSHStateListen.php 4 ./com/ssh/state/SSHStateEstabilished.php 16 ./com/ssh/state 48 ./com/ssh 52 ./com 4 ./test.php 64 . Compartilhar este post Link para o post Compartilhar em outros sites
João Batista Neto 448 Denunciar post Postado Abril 27, 2010 todos arquivos e pasta estao com chmod 777 e o php é 5.3.2 Jamais de 777 em produção, é um erro grave de segurança. Fatal error: Class 'com\ssh\SSHConnection' not found in /var/www/lighttpd/ssh/test.php on line 5 Veja esse link http://forum.imasters.com.br/public/style_emoticons/default/seta.gif http://br2.php.net/manual/pt_BR/function.spl-autoload-register.php Se estiver em ambiente Windows, bastará o uso da função sem argumentos, desde que você tenha as pastas no seu include_path No Linux, você deverá converter os separadores do namespace para separadores de diretório. Eu costumo colocar esses tipos de diretórios dentro de um outro chamado application pois, dessa forma, fica mais fácil normalizar: application/config.php <?php /** * Configurações do ambiente * @package config * @category configurations */ namespace config; /** * Caminho do diretório application * @var string */ $applicationPath = realpath( 'application' ); /** * Configurações das mensagens de erro em desenvolvimento e produção */ if ( defined( 'production' ) ){ /** * Configurações de exibição de erro para produção */ error_reporting( E_ALL & ~E_DEPRECATED ); ini_set( 'display_errors' , 'Off' ); } else { /** * Configurações de exibição de erro para desenvolvimento */ error_reporting( E_ALL | E_STRICT ); ini_set( 'display_errors' , 'On' ); } /** * Definição do include_path, diretório application assume prioridade em relação * aos originais. */ set_include_path( sprintf( '%s%s%s' , $applicationPath , PATH_SEPARATOR , get_include_path() ) ); /** * Registrando a função __autoload para carregar automaticamente nossas classes. * Para normalizar, substituimos a \ usada na hierarquia dos NAMESPACES pela constante DIRECTORY_SEPARATOR, * isso funcionará tanto em servidores Windows quanto Linux, já que a constante DIRECTORY_SEPARATOR conterá * o valor adequado para o ambiente. */ spl_autoload_register( function( $class ){ require sprintf( '%s.php' , str_replace( '\\' , DIRECTORY_SEPARATOR , $class ) ); } ); Compartilhar este post Link para o post Compartilhar em outros sites
xamaee 0 Denunciar post Postado Abril 27, 2010 tem como zipar isso ai ? http://forum.imasters.com.br/public/style_emoticons/default/joia.gif ja tentei aqui so da erro ^^ consegui, vlw, to enferrujado, parei 1 ano e pouco atras^^ nem existia namespace ainda Compartilhar este post Link para o post Compartilhar em outros sites
acm_correa 0 Denunciar post Postado Setembro 30, 2010 Pessoal, infelizmente não consegui rodar a solução =( Algum de vocês conhece esse erro? Estou tentando rodar em um servidor Linux [root@dyn529872 teste_ssh]# php index.php PHP Parse error: syntax error, unexpected T_STRING, expecting T_CONSTANT_ENCAPSED_STRING or '(' in /var/www/html/teste_ssh/index.php on line 3 You have new mail in /var/spool/mail/root [root@dyn529872 teste_ssh]# Poderiam me dar uma ajuda? Abraço Srs, Estou tentando instalar essa biblioteca já faz algum tempo. Já tentei no Cent OS, no REDHAT e no Debian porem não obtive sucesso em nenhum dos casos, alguem teria um tutorial de como instalar? Obrigado Compartilhar este post Link para o post Compartilhar em outros sites
acm_correa 0 Denunciar post Postado Novembro 4, 2010 Senhores, Finalmente consegui instalar a biblioteca sem que ela apresente erro. Estou utilizando RH 5.5 só que estou recebendo uma msg de erro quando abro a Pagina pelo apache: [Thu Nov 04 14:46:59 2010] [error] [client 9.18.218.31] PHP Warning: ssh2_connect() [<a href='function.ssh2-connect'>function.ssh2-connect</a>]: Unable to connect to 9.18.218.20 on port 22 in /var/www/html/teste_ssh01.php on line 11 [Thu Nov 04 14:46:59 2010] [error] [client 9.18.218.31] PHP Warning: ssh2_connect() [<a href='function.ssh2-connect'>function.ssh2-connect</a>]: Unable to connect to 9.18.218.20 in /var/www/html/teste_ssh01.php on line 11 Se rodo ele na linha de comando ele roda de boa: [root@xxxx html]# php teste_ssh01.php okay: logged in... Sist. Arq. Tam Usad Disp Uso% Montado em /dev/hda1 1,9G 293M 1,6G 16% / /dev/hda9 1,9G 35M 1,8G 2% /tmp /dev/hda7 4,8G 599M 3,9G 14% /opt /dev/hda6 4,8G 1,8G 2,8G 40% /home /dev/hda5 9,5G 8,1G 909M 91% /var /dev/hda3 9,5G 1,3G 7,8G 14% /usr /dev/hda2 19G 19G 0 100% /img tmpfs 993M 0 993M 0% /dev/shm /dev/hda10 74G 7,6G 63G 11% /backup <br> [root@xxxx html]# Se puderem me ajudar eu agradeço. Abraço Compartilhar este post Link para o post Compartilhar em outros sites