ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
SCP.php
Go to the documentation of this file.
1<?php
2
33namespace phpseclib\Net;
34
37
45class SCP
46{
58 const SOURCE_STRING = 2;
69 const MODE_SSH1 = 1;
73 const MODE_SSH2 = 2;
82 var $ssh;
83
91
98 var $mode;
99
112 {
113 if ($ssh instanceof SSH2) {
114 $this->mode = self::MODE_SSH2;
115 } elseif ($ssh instanceof SSH1) {
116 $this->packet_size = 50000;
117 $this->mode = self::MODE_SSH1;
118 } else {
119 return;
120 }
121
122 $this->ssh = $ssh;
123 }
124
146 function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
147 {
148 if (!isset($this->ssh)) {
149 return false;
150 }
151
152 if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
153 return false;
154 }
155
156 $temp = $this->_receive();
157 if ($temp !== chr(0)) {
158 return false;
159 }
160
161 if ($this->mode == self::MODE_SSH2) {
162 $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4;
163 }
164
165 $remote_file = basename($remote_file);
166
167 if ($mode == self::SOURCE_STRING) {
168 $size = strlen($data);
169 } else {
170 if (!is_file($data)) {
171 user_error("$data is not a valid file", E_USER_NOTICE);
172 return false;
173 }
174
175 $fp = @fopen($data, 'rb');
176 if (!$fp) {
177 return false;
178 }
179 $size = filesize($data);
180 }
181
182 $this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
183
184 $temp = $this->_receive();
185 if ($temp !== chr(0)) {
186 return false;
187 }
188
189 $sent = 0;
190 while ($sent < $size) {
191 $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
192 $this->_send($temp);
193 $sent+= strlen($temp);
194
195 if (is_callable($callback)) {
196 call_user_func($callback, $sent);
197 }
198 }
199 $this->_close();
200
201 if ($mode != self::SOURCE_STRING) {
202 fclose($fp);
203 }
204
205 return true;
206 }
207
220 function get($remote_file, $local_file = false)
221 {
222 if (!isset($this->ssh)) {
223 return false;
224 }
225
226 if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
227 return false;
228 }
229
230 $this->_send("\0");
231
232 if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
233 return false;
234 }
235
236 $this->_send("\0");
237
238 $size = 0;
239
240 if ($local_file !== false) {
241 $fp = @fopen($local_file, 'wb');
242 if (!$fp) {
243 return false;
244 }
245 }
246
247 $content = '';
248 while ($size < $info['size']) {
249 $data = $this->_receive();
250 // SCP usually seems to split stuff out into 16k chunks
251 $size+= strlen($data);
252
253 if ($local_file === false) {
254 $content.= $data;
255 } else {
256 fputs($fp, $data);
257 }
258 }
259
260 $this->_close();
261
262 if ($local_file !== false) {
263 fclose($fp);
264 return true;
265 }
266
267 return $content;
268 }
269
276 function _send($data)
277 {
278 switch ($this->mode) {
279 case self::MODE_SSH2:
280 $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data);
281 break;
282 case self::MODE_SSH1:
283 $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
284 $this->ssh->_send_binary_packet($data);
285 }
286 }
287
294 function _receive()
295 {
296 switch ($this->mode) {
297 case self::MODE_SSH2:
298 return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true);
299 case self::MODE_SSH1:
300 if (!$this->ssh->bitmap) {
301 return false;
302 }
303 while (true) {
304 $response = $this->ssh->_get_binary_packet();
306 case NET_SSH1_SMSG_STDOUT_DATA:
307 extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
308 return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length);
309 case NET_SSH1_SMSG_STDERR_DATA:
310 break;
311 case NET_SSH1_SMSG_EXITSTATUS:
312 $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
313 fclose($this->ssh->fsock);
314 $this->ssh->bitmap = 0;
315 return false;
316 default:
317 user_error('Unknown packet received', E_USER_NOTICE);
318 return false;
319 }
320 }
321 }
322 }
323
329 function _close()
330 {
331 switch ($this->mode) {
332 case self::MODE_SSH2:
333 $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true);
334 break;
335 case self::MODE_SSH1:
336 $this->ssh->disconnect();
337 }
338 }
339}
$size
Definition: RandomTest.php:84
An exception for terminatinating execution or to throw for unit testing.
const SOURCE_LOCAL_FILE
#+ @access public
Definition: SCP.php:54
_receive()
Receives a packet from an SSH server.
Definition: SCP.php:294
__construct($ssh)
Default Constructor.
Definition: SCP.php:111
_close()
Closes the connection to an SSH server.
Definition: SCP.php:329
_send($data)
Sends a packet to an SSH server.
Definition: SCP.php:276
const MODE_SSH2
SSH2 is being used.
Definition: SCP.php:73
const SOURCE_STRING
Reads data from a string.
Definition: SCP.php:58
put($remote_file, $data, $mode=self::SOURCE_STRING, $callback=null)
Uploads a file to the SCP server.
Definition: SCP.php:146
const MODE_SSH1
#-
Definition: SCP.php:69
const RESPONSE_DATA
The Response Data.
Definition: SSH1.php:174
const RESPONSE_TYPE
#-
Definition: SSH1.php:166
const CHANNEL_EXEC
#-
Definition: SSH2.php:103
$info
Definition: index.php:5
Pure-PHP implementations of SCP.
Pure-PHP implementation of SSHv1.
Pure-PHP implementation of SSHv2.
$response
$data
Definition: bench.php:6