Session.php (4343B)
1 <?php 2 3 namespace Ssh; 4 5 use InvalidArgumentException, RuntimeException; 6 7 /** 8 * SSH session 9 * 10 * @author Antoine Hérault <antoine.herault@gmail.com> 11 */ 12 class Session extends AbstractResourceHolder 13 { 14 protected $configuration; 15 protected $authentication; 16 protected $subsystems; 17 18 /** 19 * Constructor 20 * 21 * @param Configuration A Configuration instance 22 * @param Authentication An optional Authentication instance 23 */ 24 public function __construct(Configuration $configuration, Authentication $authentication = null) 25 { 26 $this->configuration = $configuration; 27 $this->authentication = $authentication; 28 $this->subsystem = array(); 29 } 30 31 /** 32 * Defines the authentication. If the 33 * 34 * @param Authentication $authentication 35 */ 36 public function setAuthentication(Authentication $authentication) 37 { 38 $firstAuthentication = null === $this->authentication; 39 40 $this->authentication = $authentication; 41 42 if ($firstAuthentication && is_resource($this->resource)) { 43 $this->authenticate(); 44 } 45 } 46 47 /** 48 * Returns the Sftp subsystem 49 * 50 * @return Sftp 51 */ 52 public function getSftp() 53 { 54 return $this->getSubsystem('sftp'); 55 } 56 57 /** 58 * Returns the Publickey subsystem 59 * 60 * @return Publickey 61 */ 62 public function getPublickey() 63 { 64 return $this->getSubsystem('publickey'); 65 } 66 67 /** 68 * Returns the Exec subsystem 69 * 70 * @return Exec 71 */ 72 public function getExec() 73 { 74 return $this->getSubsystem('exec'); 75 } 76 77 /** 78 * Returns the specified subsystem 79 * 80 * If the subsystem does not exists, it will create it 81 * 82 * @param string $name The subsystem's name 83 * 84 * @return Subsystem 85 */ 86 public function getSubsystem($name) 87 { 88 if (!isset($this->subsystems[$name])) { 89 $this->createSubsystem($name); 90 } 91 92 return $this->subsystems[$name]; 93 } 94 95 /** 96 * Creates the specified subsystem 97 * 98 * @param string $name The subsystem's name 99 * 100 * @throws InvalidArgumentException if the specified subsystem is no 101 * supported (e.g does not exist) 102 */ 103 protected function createSubsystem($name) 104 { 105 switch ($name) { 106 case 'sftp': 107 $subsystem = new Sftp($this); 108 break; 109 case 'publickey': 110 $subsystem = new Publickey($this); 111 break; 112 case 'exec': 113 $subsystem = new Exec($this); 114 break; 115 default: 116 throw new InvalidArgumentException(sprintf('The subsystem \'%s\' is not supported.', $name)); 117 } 118 119 $this->subsystems[$name] = $subsystem; 120 } 121 122 /** 123 * Creates the session resource 124 * 125 * If there is a defined authentication, it will authenticate the session 126 * 127 * @throws RuntimeException if the connection fail 128 */ 129 protected function createResource() 130 { 131 $resource = $this->connect($this->configuration->asArguments()); 132 133 if (!is_resource($resource)) { 134 throw new RuntimeException('The SSH connection failed.'); 135 } 136 137 $this->resource = $resource; 138 139 if (null !== $this->authentication) { 140 $this->authenticate(); 141 } 142 } 143 144 /** 145 * Opens a connection with the remote server using the given arguments 146 * 147 * @param array $arguments An array of arguments 148 * 149 * @return resource 150 */ 151 protected function connect(array $arguments) 152 { 153 return call_user_func_array('ssh2_connect', $arguments); 154 } 155 156 /** 157 * Authenticates over the current SSH session and using the defined 158 * authentication 159 * 160 * @throws RuntimeException on authentication failure 161 */ 162 protected function authenticate() 163 { 164 $authenticated = $this->authentication->authenticate($this->resource); 165 166 if (!$authenticated) { 167 throw new RuntimeException('The authentication over the current SSH connection failed.'); 168 } 169 } 170 171 /** 172 * @return Configuration 173 */ 174 public function getConfiguration() 175 { 176 return $this->configuration; 177 } 178 }