diff --git a/README.md b/README.md index 119352b..bc3b711 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,23 @@ # socks5-proxy -Socks5 proxy written in PHP based on [workerman](https://github.com/walkor/Workerman). +Socks5 proxy written in PHP based on [workerman](https://github.com/walkor/Workerman). Now with username/password authentication according to RFC 1929. ## Install 1. ```git clone https://github.com/walkor/php-socks5``` 2. ```composer install``` +## Config +Edit file ```config.php``` + ## Start -php start.php start -d +```php start.php start -d``` ## Stop -php start.php stop +```php start.php stop``` ## Status -php start.php status +```php start.php status``` -## Other links +## Other links https://github.com/walkor/shadowsocks-php https://github.com/walkor/php-http-proxy diff --git a/config.php b/config.php new file mode 100644 index 0000000..8f9188b --- /dev/null +++ b/config.php @@ -0,0 +1,5 @@ +onConnect = function($connection) @@ -32,19 +36,56 @@ $worker->onConnect = function($connection) }; $worker->onMessage = function($connection, $buffer) { + global $AUTH_ENABLED, $USERNAME, $PASSWORD; switch($connection->stage) { case STAGE_INIT: + if ($AUTH_ENABLED) + { + $methodslen = ord($buffer[1]); + $methods = array(); + for ($i = 0; $i < strlen($buffer)-3; $i++) + { + array_push($methods, ord($buffer[$i+3])); + } + if (in_array(METHOD_USER_PASS, $methods)) + { + $connection->send("\x05\x02"); + $connection->stage = STAGE_AUTH; + return; + } + echo "client does not support user/pass auth\n"; + $connection->send("\x05\xff"); + $connection->stage = STAGE_DESTROYED; + $connection->close(); + return; + } $connection->send("\x05\x00"); $connection->stage = STAGE_ADDR; return; + case STAGE_AUTH: + $userlen = ord($buffer[1]); + $user = substr($buffer, 2, $userlen); + $passlen = ord($buffer[2 + $userlen]); + $pass = substr($buffer, 3 + $userlen, $passlen); + if ($user == $USERNAME && $pass == $PASSWORD) + { + $connection->send("\x05\x00"); + $connection->stage = STAGE_ADDR; + return; + } + echo "auth failed\n"; + $connection->send("\x05\x01"); + $connection->stage = STAGE_DESTROYED; + $connection->close(); + return; case STAGE_ADDR: $cmd = ord($buffer[1]); if($cmd != CMD_CONNECT) { - echo "bad cmd $cmd\n"; - $connection->close(); - return; + echo "bad cmd $cmd\n"; + $connection->close(); + return; } $header_data = parse_socket5_header($buffer); if(!$header_data)