144 lines
3.4 KiB
PHP
144 lines
3.4 KiB
PHP
<?php
|
|
|
|
//-----------------------------------------------------------------------
|
|
// LegacyWorlds Beta 5
|
|
// Game libraries
|
|
//
|
|
// lib/pcheck_thread.inc
|
|
//
|
|
// This library contains the code of the open proxy detector's scanning
|
|
// threads.
|
|
//
|
|
// Copyright(C) 2004-2008, DeepClone Development
|
|
//-----------------------------------------------------------------------
|
|
|
|
|
|
class pcheck_thread {
|
|
|
|
/** The process ID of the thread.
|
|
*/
|
|
public $pid;
|
|
|
|
/** The message queue the thread is bound to. Undefined in the
|
|
* parent process.
|
|
*/
|
|
private $queue;
|
|
|
|
/** This property indicates that the thread has ended.
|
|
*/
|
|
public $ended = false;
|
|
|
|
|
|
/** The constructor forks (throwing an exception on failure), then
|
|
* depending on whether it is in the parent process or in the child,
|
|
* returns or enters the instruction loop.
|
|
*/
|
|
public function __construct($queue) {
|
|
$pid = @pcntl_fork();
|
|
if ($pid == -1) {
|
|
throw new Exception("Unable to fork");
|
|
}
|
|
|
|
if ($pid != 0) {
|
|
// In the parent, store the child's PID and get going.
|
|
$this->pid = $pid;
|
|
$this->free = true;
|
|
$this->queue = $queue;
|
|
return;
|
|
}
|
|
|
|
// In the child, store our PID and the queue, then starts
|
|
// waiting for instructions.
|
|
$this->pid = posix_getpid();
|
|
$this->queue = $queue;
|
|
$this->waitLoop();
|
|
}
|
|
|
|
|
|
/** This method is called by the manager to send messages to the
|
|
* threads.
|
|
*/
|
|
public function send($message) {
|
|
return $this->ended ? false : msg_send($this->queue, $this->pid, $message, true);
|
|
}
|
|
|
|
|
|
/** This method implements the instruction loop.
|
|
*/
|
|
private function waitLoop() {
|
|
$quit = false;
|
|
$error = false;
|
|
|
|
do {
|
|
$success = msg_receive($this->queue, $this->pid, $type, 32768, $message, true);
|
|
if (! $success) {
|
|
l::error("Child failed to receive a message");
|
|
$quit = $error = true;
|
|
} elseif ($message['type'] == 'QUIT') {
|
|
$quit = true;
|
|
} elseif ($message['type'] == 'SCAN') {
|
|
list($host, $port) = $message['scan'];
|
|
|
|
$found = $this->executeCheck($host, $port, "GET")
|
|
|| $this->executeCheck($host, $port, "POST");
|
|
|
|
if (!msg_send($this->queue, 1, array($this->pid, $host, $found), true)) {
|
|
l::error("Child failed to send message");
|
|
$quit = $error = true;
|
|
}
|
|
} else {
|
|
l::notice("Unknown message {$message['type']} received");
|
|
}
|
|
} while (!$quit);
|
|
|
|
exit($error ? 1 : 0);
|
|
}
|
|
|
|
|
|
/** This method will try to check one port for open proxy software, using
|
|
* a specific method (POST or GET).
|
|
*/
|
|
private function executeCheck($ipAddress, $port, $method) {
|
|
$key = md5(uniqid(rand()));
|
|
|
|
// Open the socket
|
|
$socket = @fsockopen("tcp://$ipAddress", $port, $errno, $errstr, pcheck_manager::$timeout);
|
|
if ($socket === FALSE) {
|
|
return false;
|
|
}
|
|
|
|
// Make sure I/O doesn't timeout
|
|
stream_set_timeout($socket, pcheck_manager::$timeout);
|
|
|
|
// Send the request
|
|
$result = @fwrite($socket, preg_replace('/__key__/', $key, pcheck_manager::$requests[$method]));
|
|
if ($result !== FALSE) {
|
|
$info = stream_get_meta_data($socket);
|
|
if ($info['timed_out']) {
|
|
$result = false;
|
|
}
|
|
}
|
|
|
|
// Get the page
|
|
if ($result !== FALSE) {
|
|
$result = @fread($socket, 4096);
|
|
}
|
|
if ($result !== FALSE) {
|
|
$info = stream_get_meta_data($socket);
|
|
if ($info['timed_out']) {
|
|
$result = false;
|
|
}
|
|
}
|
|
|
|
// Close the socket
|
|
@fclose($socket);
|
|
if ($result === FALSE) {
|
|
return false;
|
|
}
|
|
|
|
return preg_match("/Key is \\<$key\\>/", $result);
|
|
}
|
|
}
|
|
|
|
|
|
?>
|