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 | namespace PHPDaemon\BoundSocket; |
||
3 | |||
4 | use PHPDaemon\Core\Daemon; |
||
5 | use PHPDaemon\Core\EventLoop; |
||
6 | use PHPDaemon\FS\FileSystem; |
||
7 | use PHPDaemon\Traits\EventLoopContainer; |
||
8 | |||
9 | /** |
||
10 | * Generic |
||
11 | * |
||
12 | * @property mixed addr |
||
13 | * @package Coress |
||
14 | * |
||
15 | * @author Vasily Zorin <[email protected]> |
||
16 | * @dynamic_fields |
||
17 | */ |
||
18 | abstract class Generic |
||
19 | { |
||
20 | use \PHPDaemon\Traits\ClassWatchdog; |
||
21 | use EventLoopContainer; |
||
22 | |||
23 | /** |
||
24 | * Enabled? |
||
25 | * @var boolean |
||
26 | */ |
||
27 | protected $enabled = false; |
||
28 | |||
29 | /** |
||
30 | * File descriptor |
||
31 | * @var mixed |
||
32 | */ |
||
33 | protected $fd; |
||
34 | |||
35 | /** |
||
36 | * Event |
||
37 | * @var \EventListener\Event |
||
38 | */ |
||
39 | protected $ev; |
||
40 | |||
41 | /** |
||
42 | * PID of process which bound this socket |
||
43 | * @var int |
||
44 | */ |
||
45 | protected $pid; |
||
46 | |||
47 | /** |
||
48 | * Pool |
||
49 | * @var \PHPDaemon\Network\Pool |
||
50 | */ |
||
51 | protected $pool; |
||
52 | |||
53 | /** |
||
54 | * Listener mode? |
||
55 | * @var boolean |
||
56 | */ |
||
57 | protected $listenerMode = false; |
||
58 | |||
59 | /** |
||
60 | * Context |
||
61 | * @var mixed |
||
62 | */ |
||
63 | protected $ctx; |
||
64 | |||
65 | /** |
||
66 | * URI |
||
67 | * @var string |
||
68 | */ |
||
69 | protected $uri; |
||
70 | |||
71 | /** |
||
72 | * Context name |
||
73 | * @var string |
||
74 | */ |
||
75 | protected $ctxname; |
||
76 | |||
77 | /** |
||
78 | * Reuse? |
||
79 | * @var boolean |
||
80 | */ |
||
81 | protected $reuse = true; |
||
82 | |||
83 | /** |
||
84 | * SSL |
||
85 | * @var mixed |
||
86 | */ |
||
87 | protected $ssl; |
||
88 | |||
89 | /** |
||
90 | * TLS |
||
91 | * @var mixed |
||
92 | */ |
||
93 | protected $tls; |
||
94 | |||
95 | /** |
||
96 | * Erroneous? |
||
97 | * @var boolean |
||
98 | */ |
||
99 | protected $erroneous = false; |
||
100 | |||
101 | /** |
||
102 | * Private key file |
||
103 | * @var string |
||
104 | */ |
||
105 | protected $pkfile; |
||
106 | |||
107 | /** |
||
108 | * Certificate file |
||
109 | * @var string |
||
110 | */ |
||
111 | protected $certfile; |
||
112 | |||
113 | /** |
||
114 | * CA file |
||
115 | * @var string |
||
116 | */ |
||
117 | protected $cafile; |
||
118 | |||
119 | /** |
||
120 | * Passphrase |
||
121 | * @var string |
||
122 | */ |
||
123 | protected $passphrase; |
||
124 | |||
125 | /** |
||
126 | * Verify peer? |
||
127 | * @var boolean |
||
128 | */ |
||
129 | protected $verifypeer = false; |
||
130 | |||
131 | /** |
||
132 | * Verify depth |
||
133 | * @var integer |
||
134 | */ |
||
135 | protected $verifydepth; |
||
136 | |||
137 | /** |
||
138 | * Allow self-signed? |
||
139 | * @var boolean |
||
140 | */ |
||
141 | protected $allowselfsigned = true; |
||
142 | |||
143 | /** |
||
144 | * Source |
||
145 | * @var string |
||
146 | */ |
||
147 | protected $source; |
||
148 | |||
149 | /** |
||
150 | * Revision |
||
151 | * @var integer |
||
152 | */ |
||
153 | protected $revision; |
||
154 | |||
155 | /** |
||
156 | * Constructor |
||
157 | * @param string URI |
||
158 | * @return object |
||
0 ignored issues
–
show
|
|||
159 | */ |
||
160 | public function __construct($uri) |
||
161 | { |
||
162 | $this->uri = is_array($uri) ? $uri : \PHPDaemon\Config\_Object::parseCfgUri($uri); |
||
0 ignored issues
–
show
It seems like
is_array($uri) ? $uri : ...ject::parseCfgUri($uri) of type false or array is incompatible with the declared type string of property $uri .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
163 | if (!$this->uri) { |
||
164 | return; |
||
165 | } |
||
166 | $this->importParams(); |
||
167 | if ($this->ssl || $this->tls) { |
||
168 | $this->initSecureContext(); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * toString handler |
||
174 | * @return string |
||
175 | */ |
||
176 | public function __toString() |
||
177 | { |
||
178 | return $this->uri['uri']; |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * Get URI |
||
183 | * @return string |
||
184 | */ |
||
185 | public function getUri() |
||
186 | { |
||
187 | return $this->uri; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Get port |
||
192 | * @return string|null |
||
193 | */ |
||
194 | public function getPort() |
||
195 | { |
||
196 | return isset($this->port) ? $this->port : null; |
||
0 ignored issues
–
show
The property
port does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Import parameters |
||
201 | * @return void |
||
202 | */ |
||
203 | protected function importParams() |
||
204 | { |
||
205 | View Code Duplication | foreach ($this->uri['params'] as $key => $val) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
206 | if (isset($this->{$key}) && is_bool($this->{$key})) { |
||
207 | $this->{$key} = (bool)$val; |
||
208 | continue; |
||
209 | } |
||
210 | if (!property_exists($this, $key)) { |
||
211 | Daemon::log(get_class($this) . ': unrecognized setting \'' . $key . '\''); |
||
212 | continue; |
||
213 | } |
||
214 | $this->{$key} = $val; |
||
215 | } |
||
216 | if (property_exists($this, 'port') && !isset($this->port)) { |
||
217 | if (isset($this->uri['port'])) { |
||
218 | $this->port = $this->uri['port']; |
||
219 | } elseif ($this->defaultPort) { |
||
0 ignored issues
–
show
The property
defaultPort does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
220 | $this->port = $this->defaultPort; |
||
221 | } |
||
222 | } |
||
223 | if (property_exists($this, 'host') && !isset($this->host)) { |
||
224 | if (isset($this->uri['host'])) { |
||
225 | $this->host = $this->uri['host']; |
||
0 ignored issues
–
show
The property
host does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
226 | } |
||
227 | } |
||
228 | if (!$this->ctxname) { |
||
229 | return; |
||
230 | } |
||
231 | View Code Duplication | if (!isset(Daemon::$config->{'TransportContext:' . $this->ctxname})) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
232 | Daemon::log(get_class($this) . ': undefined transport context \'' . $this->ctxname . '\''); |
||
233 | return; |
||
234 | } |
||
235 | $ctx = Daemon::$config->{'TransportContext:' . $this->ctxname}; |
||
236 | View Code Duplication | foreach ($ctx as $key => $entry) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
237 | $value = ($entry instanceof \PHPDaemon\Config\Entry\Generic) ? $entry->value : $entry; |
||
238 | if (isset($this->{$key}) && is_bool($this->{$key})) { |
||
239 | $this->{$key} = (bool)$value; |
||
240 | continue; |
||
241 | } |
||
242 | if (!property_exists($this, $key)) { |
||
243 | Daemon::log(get_class($this) . ': unrecognized setting in transport context \'' . $this->ctxname . '\': \'' . $key . '\''); |
||
244 | continue; |
||
245 | } |
||
246 | $this->{$key} = $value; |
||
247 | } |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Initialize SSL/TLS context |
||
252 | * @return void |
||
253 | */ |
||
254 | protected function initSecureContext() |
||
255 | { |
||
256 | View Code Duplication | if (!\EventUtil::sslRandPoll()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
257 | Daemon::$process->log(get_class($this->pool) . ': EventUtil::sslRandPoll failed'); |
||
258 | $this->erroneous = true; |
||
259 | return; |
||
260 | } |
||
261 | if (!FileSystem::checkFileReadable($this->certfile) || !FileSystem::checkFileReadable($this->pkfile)) { |
||
262 | Daemon::log('Couldn\'t read ' . $this->certfile . ' or ' . $this->pkfile . ' file. To generate a key' . PHP_EOL |
||
263 | . 'and self-signed certificate, run' . PHP_EOL |
||
264 | . ' openssl genrsa -out ' . escapeshellarg($this->pkfile) . ' 2048' . PHP_EOL |
||
265 | . ' openssl req -new -key ' . escapeshellarg($this->pkfile) . ' -out cert.req' . PHP_EOL |
||
266 | . ' openssl x509 -req -days 365 -in cert.req -signkey ' . escapeshellarg($this->pkfile) . ' -out ' . escapeshellarg($this->certfile)); |
||
267 | |||
268 | return; |
||
269 | } |
||
270 | $params = [ |
||
271 | \EventSslContext::OPT_LOCAL_CERT => $this->certfile, |
||
272 | \EventSslContext::OPT_LOCAL_PK => $this->pkfile, |
||
273 | \EventSslContext::OPT_VERIFY_PEER => $this->verifypeer, |
||
274 | \EventSslContext::OPT_ALLOW_SELF_SIGNED => $this->allowselfsigned, |
||
275 | ]; |
||
276 | if ($this->passphrase !== null) { |
||
277 | $params[\EventSslContext::OPT_PASSPHRASE] = $this->passphrase; |
||
278 | } |
||
279 | if ($this->verifydepth !== null) { |
||
280 | $params[\EventSslContext::OPT_VERIFY_DEPTH] = $this->verifydepth; |
||
281 | } |
||
282 | if ($this->cafile !== null) { |
||
283 | $params[\EventSslContext::OPT_CA_FILE] = $this->cafile; |
||
284 | } |
||
285 | if ($this->tls === true) { |
||
286 | $method = \EventSslContext::TLS_SERVER_METHOD; |
||
287 | } elseif ($this->tls === 'v11') { |
||
288 | $method = \EventSslContext::TLSv11_SERVER_METHOD; |
||
289 | } elseif ($this->tls === 'v12') { |
||
290 | $method = \EventSslContext::TLSv12_SERVER_METHOD; |
||
291 | } elseif ($this->ssl === 'v3' || $this->ssl === true || $this->ssl === '1') { |
||
292 | $method = \EventSslContext::SSLv3_SERVER_METHOD; |
||
293 | } elseif ($this->ssl === 'v2') { |
||
294 | $method = \EventSslContext::SSLv2_SERVER_METHOD; |
||
295 | } elseif ($this->ssl === 'v23') { |
||
296 | $method = \EventSslContext::SSLv23_SERVER_METHOD; |
||
297 | } elseif ($this->ssl) { |
||
298 | Daemon::log(get_class($this) . ': unrecognized SSL version \'' . $this->ssl . '\''); |
||
299 | return; |
||
300 | } else { |
||
301 | return; |
||
302 | } |
||
303 | $this->ctx = new \EventSslContext($method, $params); |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Attach to ConnectionPool |
||
308 | * @param ConnectionPool |
||
309 | * @return void |
||
310 | */ |
||
311 | public function attachTo(\PHPDaemon\Network\Pool $pool) |
||
312 | { |
||
313 | $this->pool = $pool; |
||
314 | $this->pool->attachBound($this); |
||
0 ignored issues
–
show
The method
attachBound does not exist on object<PHPDaemon\Network\Pool> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
315 | } |
||
316 | |||
317 | /** |
||
318 | * Route incoming request to related application |
||
319 | * @param resource Socket |
||
320 | * @param string $fd |
||
321 | * @return void |
||
322 | */ |
||
323 | public function setFd($fd) |
||
324 | { |
||
325 | $this->fd = $fd; |
||
326 | $this->pid = posix_getpid(); |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * Called when socket is bound |
||
331 | * @return boolean|null Success |
||
332 | */ |
||
333 | protected function onBound() |
||
334 | { |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * Enable socket events |
||
339 | * @return void |
||
340 | */ |
||
341 | View Code Duplication | public function enable() |
|
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. ![]() |
|||
342 | { |
||
343 | if ($this->enabled) { |
||
344 | return; |
||
345 | } |
||
346 | if (!$this->fd) { |
||
347 | return; |
||
348 | } |
||
349 | $this->enabled = true; |
||
350 | if ($this->ev === null) { |
||
351 | if ($this->eventLoop === null) { |
||
352 | $this->eventLoop = EventLoop::$instance; |
||
353 | } |
||
354 | $this->ev = $this->eventLoop->listener( |
||
355 | [$this, 'onAcceptEv'], |
||
356 | null, |
||
357 | \EventListener::OPT_CLOSE_ON_FREE | \EventListener::OPT_REUSEABLE, |
||
358 | -1, |
||
359 | $this->fd |
||
360 | ); |
||
361 | $this->onBound(); |
||
362 | } else { |
||
363 | $this->ev->enable(); |
||
364 | } |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * @param \EventListener $listener |
||
369 | * @param $fd |
||
370 | * @param $addrPort |
||
371 | * @param $ctx |
||
372 | */ |
||
373 | public function onAcceptEv(\EventListener $listener, $fd, $addrPort, $ctx) |
||
0 ignored issues
–
show
|
|||
374 | { |
||
375 | $class = $this->pool->connectionClass; |
||
376 | if (!class_exists($class) || !is_subclass_of($class, '\\PHPDaemon\\Network\\Connection')) { |
||
377 | Daemon::log(get_class($this) . ' (' . get_class($this->pool) . '): onAcceptEv: wrong connectionClass: ' . $class); |
||
378 | return; |
||
379 | } |
||
380 | $conn = new $class(null, $this->pool); |
||
381 | $conn->setParentSocket($this); |
||
382 | |||
383 | if (!$this instanceof UNIX) { |
||
384 | $conn->setPeername($addrPort[0], $addrPort[1]); |
||
385 | } |
||
386 | |||
387 | if ($this->ctx) { |
||
388 | $conn->setContext($this->ctx, \EventBufferEvent::SSL_ACCEPTING); |
||
389 | } |
||
390 | |||
391 | $conn->setFd($fd); |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Disable all events of sockets |
||
396 | * @return void |
||
397 | */ |
||
398 | public function disable() |
||
399 | { |
||
400 | if (!$this->enabled) { |
||
401 | return; |
||
402 | } |
||
403 | $this->enabled = false; |
||
404 | if ($this->ev instanceof \Event) { |
||
0 ignored issues
–
show
The class
Event does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
405 | $this->ev->del(); |
||
406 | } elseif ($this->ev instanceof \EventListener) { |
||
0 ignored issues
–
show
The class
EventListener does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
407 | $this->ev->disable(); |
||
408 | } |
||
409 | } |
||
410 | |||
411 | /** |
||
412 | * Close each of binded sockets. |
||
413 | * @return void |
||
414 | */ |
||
415 | public function close() |
||
416 | { |
||
417 | if (isset($this->ev)) { |
||
418 | $this->ev = null; |
||
419 | } |
||
420 | if ($this->pid !== posix_getpid()) { // preventing closing pre-bound sockets in workers |
||
421 | return; |
||
422 | } |
||
423 | if (is_resource($this->fd)) { |
||
424 | socket_close($this->fd); |
||
425 | } |
||
426 | } |
||
427 | |||
428 | /** |
||
429 | * Finishes Generic |
||
430 | * @return void |
||
431 | */ |
||
432 | public function finish() |
||
433 | { |
||
434 | $this->disable(); |
||
435 | $this->close(); |
||
436 | $this->pool->detachBound($this); |
||
0 ignored issues
–
show
The method
detachBound does not exist on object<PHPDaemon\Network\Pool> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Destructor |
||
441 | * @return void |
||
442 | */ |
||
443 | public function __destruct() |
||
444 | { |
||
445 | $this->close(); |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Bind given addreess |
||
450 | * @return boolean Success. |
||
451 | */ |
||
452 | abstract public function bindSocket(); |
||
453 | |||
454 | /** |
||
455 | * Checks if the CIDR-mask matches the IP |
||
456 | * @param string CIDR-mask |
||
457 | * @param string IP |
||
458 | * @return boolean Result |
||
459 | */ |
||
460 | public static function netMatch($CIDR, $IP) |
||
461 | { |
||
462 | /* TODO: IPV6 */ |
||
463 | if (is_array($CIDR)) { |
||
464 | foreach ($CIDR as &$v) { |
||
465 | if (self::netMatch($v, $IP)) { |
||
466 | return true; |
||
467 | } |
||
468 | } |
||
469 | |||
470 | return false; |
||
471 | } |
||
472 | |||
473 | $e = explode('/', $CIDR, 2); |
||
474 | |||
475 | if (!isset($e[1])) { |
||
476 | return $e[0] === $IP; |
||
477 | } |
||
478 | |||
479 | return (ip2long($IP) & ~((1 << (32 - $e[1])) - 1)) === ip2long($e[0]); |
||
480 | } |
||
481 | } |
||
482 |
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.