This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Dazzle\SSH\Driver; |
||
4 | |||
5 | use Dazzle\Event\BaseEventEmitterTrait; |
||
6 | use Dazzle\Loop\Timer\TimerInterface; |
||
7 | use Dazzle\Loop\LoopAwareTrait; |
||
8 | use Dazzle\SSH\Driver\Sftp\SftpResource; |
||
9 | use Dazzle\SSH\SSH2DriverInterface; |
||
10 | use Dazzle\SSH\SSH2Interface; |
||
11 | use Dazzle\SSH\SSH2ResourceInterface; |
||
12 | use Dazzle\Throwable\Exception\Logic\ResourceUndefinedException; |
||
13 | use Dazzle\Throwable\Exception\Runtime\ExecutionException; |
||
14 | use Error; |
||
15 | use Exception; |
||
16 | |||
17 | |||
18 | class Sftp implements SSH2DriverInterface |
||
19 | { |
||
20 | use BaseEventEmitterTrait; |
||
21 | use LoopAwareTrait; |
||
22 | |||
23 | /** |
||
24 | * @var int |
||
25 | */ |
||
26 | const BUFFER_SIZE = 4096; |
||
27 | |||
28 | /** |
||
29 | * @var SSH2Interface |
||
30 | */ |
||
31 | protected $ssh2; |
||
32 | |||
33 | /** |
||
34 | * @var resource |
||
35 | */ |
||
36 | protected $conn; |
||
37 | |||
38 | /** |
||
39 | * @var float |
||
40 | */ |
||
41 | protected $interval; |
||
42 | |||
43 | /** |
||
44 | * @var resource |
||
45 | */ |
||
46 | protected $resource; |
||
47 | |||
48 | /** |
||
49 | * @var SftpResource[]|SSH2ResourceInterface[] |
||
50 | */ |
||
51 | protected $resources; |
||
52 | |||
53 | /** |
||
54 | * @var bool |
||
55 | */ |
||
56 | protected $paused; |
||
57 | |||
58 | /** |
||
59 | * @var TimerInterface|null |
||
60 | */ |
||
61 | private $timer; |
||
62 | |||
63 | /** |
||
64 | * @var int |
||
65 | */ |
||
66 | private $resourcesCounter; |
||
67 | |||
68 | /** |
||
69 | * @var string |
||
70 | */ |
||
71 | private $buffer; |
||
72 | |||
73 | /** |
||
74 | * @var string |
||
75 | */ |
||
76 | private $prefix; |
||
77 | |||
78 | /** |
||
79 | * @param SSH2Interface $ssh2 |
||
80 | * @param resource $conn |
||
81 | * @param float $interval |
||
82 | */ |
||
83 | 21 | View Code Duplication | public function __construct(SSH2Interface $ssh2, $conn, $interval = 1e-1) |
0 ignored issues
–
show
|
|||
84 | { |
||
85 | 21 | $this->ssh2 = $ssh2; |
|
86 | 21 | $this->conn = $conn; |
|
87 | 21 | $this->interval = $interval; |
|
88 | |||
89 | 21 | $this->loop = $ssh2->getLoop(); |
|
90 | |||
91 | 21 | $this->resource = null; |
|
92 | 21 | $this->resources = []; |
|
93 | 21 | $this->paused = true; |
|
94 | |||
95 | 21 | $this->timer = null; |
|
96 | 21 | $this->resourcesCounter = 0; |
|
97 | 21 | $this->buffer = ''; |
|
98 | 21 | $this->prefix = ''; |
|
99 | |||
100 | 21 | $this->resume(); |
|
101 | 21 | } |
|
102 | |||
103 | /** |
||
104 | * |
||
105 | */ |
||
106 | 13 | public function __destruct() |
|
107 | { |
||
108 | 13 | $this->disconnect(); |
|
109 | |||
110 | |||
111 | 13 | } |
|
112 | |||
113 | /** |
||
114 | * @override |
||
115 | * @inheritDoc |
||
116 | */ |
||
117 | 1 | public function getName() |
|
118 | { |
||
119 | 1 | return 'sftp'; |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * @override |
||
124 | * @inheritDoc |
||
125 | */ |
||
126 | 4 | View Code Duplication | public function connect() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
127 | { |
||
128 | 4 | if ($this->resource !== null) |
|
129 | { |
||
130 | 1 | return; |
|
131 | } |
||
132 | |||
133 | 3 | $resource = $this->createConnection($this->conn); |
|
134 | |||
135 | 3 | if (!$resource || !is_resource($resource)) |
|
136 | { |
||
137 | 2 | $this->emit('error', [ $this, new ExecutionException('SSH2:Sftp could not be connected.') ]); |
|
138 | 2 | return; |
|
139 | } |
||
140 | |||
141 | 1 | $this->resource = $resource; |
|
142 | |||
143 | 1 | $this->emit('connect', [ $this ]); |
|
144 | 1 | } |
|
145 | |||
146 | /** |
||
147 | * @override |
||
148 | * @inheritDoc |
||
149 | */ |
||
150 | 16 | View Code Duplication | public function disconnect() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
151 | { |
||
152 | 16 | if ($this->resource === null || !is_resource($this->resource)) |
|
153 | { |
||
154 | 13 | return; |
|
155 | } |
||
156 | |||
157 | 3 | $this->pause(); |
|
158 | |||
159 | 3 | foreach ($this->resources as $resource) |
|
160 | { |
||
161 | 1 | $resource->close(); |
|
162 | } |
||
163 | |||
164 | 3 | $this->handleDisconnect(); |
|
165 | 3 | $this->emit('disconnect', [ $this ]); |
|
166 | 3 | } |
|
167 | |||
168 | /** |
||
169 | * @override |
||
170 | * @inheritDoc |
||
171 | */ |
||
172 | 3 | public function isConnected() |
|
173 | { |
||
174 | 3 | return $this->resource !== null && is_resource($this->resource); |
|
175 | } |
||
176 | |||
177 | /** |
||
178 | * @override |
||
179 | * @inheritDoc |
||
180 | */ |
||
181 | 3 | View Code Duplication | public function pause() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
182 | { |
||
183 | 3 | if (!$this->paused) |
|
184 | { |
||
185 | 2 | $this->paused = true; |
|
186 | |||
187 | 2 | if ($this->timer !== null) |
|
188 | { |
||
189 | 2 | $this->timer->cancel(); |
|
190 | 2 | $this->timer = null; |
|
191 | } |
||
192 | } |
||
193 | 3 | } |
|
194 | |||
195 | /** |
||
196 | * @override |
||
197 | * @inheritDoc |
||
198 | */ |
||
199 | 21 | View Code Duplication | public function resume() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
200 | { |
||
201 | 21 | if ($this->paused) |
|
202 | { |
||
203 | 21 | $this->paused = false; |
|
204 | |||
205 | 21 | if ($this->timer === null) |
|
206 | { |
||
207 | 21 | $this->timer = $this->loop->addPeriodicTimer($this->interval, [ $this, 'handleHeartbeat' ]); |
|
208 | } |
||
209 | } |
||
210 | 21 | } |
|
211 | |||
212 | /** |
||
213 | * @override |
||
214 | * @inheritDoc |
||
215 | */ |
||
216 | 6 | public function isPaused() |
|
217 | { |
||
218 | 6 | return $this->paused; |
|
219 | } |
||
220 | |||
221 | /** |
||
222 | * @override |
||
223 | * @inheritDoc |
||
224 | */ |
||
225 | public function open($resource = null, $flags = 'r') |
||
226 | { |
||
227 | if (!$this->isConnected()) |
||
228 | { |
||
229 | throw new ResourceUndefinedException('Tried to open resource before establishing SSH2 connection!'); |
||
230 | } |
||
231 | |||
232 | $stream = @fopen("ssh2.sftp://" . $this->resource . $resource, $flags); |
||
233 | |||
234 | if (!$stream) |
||
235 | { |
||
236 | throw new ResourceUndefinedException("Access to SFTP resource [$resource] denied!"); |
||
237 | } |
||
238 | |||
239 | $resource = new SftpResource($this, $stream); |
||
240 | $resource->on('open', function(SSH2ResourceInterface $resource) { |
||
241 | $this->emit('resource:open', [ $this, $resource ]); |
||
242 | }); |
||
243 | $resource->on('close', function(SSH2ResourceInterface $resource) { |
||
244 | $this->removeResource($resource->getId()); |
||
245 | $this->emit('resource:close', [ $this, $resource ]); |
||
246 | }); |
||
247 | |||
248 | $this->resources[$resource->getId()] = $resource; |
||
249 | $this->resourcesCounter++; |
||
250 | $this->resume(); |
||
251 | |||
252 | return $resource; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Determine whether connection is still open. |
||
257 | * |
||
258 | * @internal |
||
259 | */ |
||
260 | public function handleHeartbeat() |
||
261 | { |
||
262 | $fp = @fopen("ssh2.sftp://" . $this->resource . "/.", "r"); |
||
263 | |||
264 | if (!$fp || !is_resource($fp)) |
||
265 | { |
||
266 | return $this->ssh2->disconnect(); |
||
267 | } |
||
268 | |||
269 | fclose($fp); |
||
270 | |||
271 | $this->handleData(); |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * Handle data. |
||
276 | * |
||
277 | * @internal |
||
278 | */ |
||
279 | public function handleData() |
||
280 | { |
||
281 | if ($this->paused || $this->resourcesCounter === 0) |
||
282 | { |
||
283 | return; |
||
284 | } |
||
285 | |||
286 | // handle all reading |
||
287 | foreach ($this->resources as $resource) |
||
288 | { |
||
289 | if (!$resource->isPaused() && $resource->isReadable()) |
||
0 ignored issues
–
show
The method
isPaused does only exist in Dazzle\SSH\Driver\Sftp\SftpResource , but not in Dazzle\SSH\SSH2ResourceInterface .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
290 | { |
||
291 | $resource->handleRead(); |
||
0 ignored issues
–
show
The method
handleRead does only exist in Dazzle\SSH\Driver\Sftp\SftpResource , but not in Dazzle\SSH\SSH2ResourceInterface .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
292 | } |
||
293 | } |
||
294 | |||
295 | // handle all writing |
||
296 | foreach ($this->resources as $resource) |
||
297 | { |
||
298 | if (!$resource->isPaused() && $resource->isWritable()) |
||
299 | { |
||
300 | $resource->handleWrite(); |
||
0 ignored issues
–
show
The method
handleWrite does only exist in Dazzle\SSH\Driver\Sftp\SftpResource , but not in Dazzle\SSH\SSH2ResourceInterface .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
301 | } |
||
302 | } |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * |
||
307 | */ |
||
308 | 1 | protected function handleDisconnect() |
|
309 | { |
||
310 | 1 | @fclose($this->resource); |
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
311 | 1 | $this->resource = null; |
|
312 | 1 | } |
|
313 | |||
314 | /** |
||
315 | * @param resource $conn |
||
316 | * @return resource |
||
317 | */ |
||
318 | protected function createConnection($conn) |
||
319 | { |
||
320 | return @ssh2_shell($conn); |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Remove resource from known collection. |
||
325 | * |
||
326 | * @param string $prefix |
||
327 | */ |
||
328 | View Code Duplication | private function removeResource($prefix) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
329 | { |
||
330 | if (!isset($this->resources[$prefix])) |
||
331 | { |
||
332 | return; |
||
333 | } |
||
334 | |||
335 | unset($this->resources[$prefix]); |
||
336 | $this->resourcesCounter--; |
||
337 | |||
338 | if ($this->resourcesCounter === 0) |
||
339 | { |
||
340 | $this->pause(); |
||
341 | } |
||
342 | } |
||
343 | } |
||
344 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.