Skip to content

Commit

Permalink
update README
Browse files Browse the repository at this point in the history
  • Loading branch information
yuseferi committed Jun 14, 2020
1 parent 3f45a0d commit 5d034c0
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 1 deletion.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
# telegram-php-socks5
php-socks5 proxy server for using in Telegram
Very simple php-socks5 proxy server for using in Telegram.
Socks5 proxy written in PHP based on [workerman](https://github.com/walkor/Workerman).

**This is adapted version of Workerman php-socks5 version that support telegram.**

## Install
1. ```git clone https://github.com/yuseferi/telegram-php-socks5```

2. ```composer install```

## Config
Edit file ```config.php``` if you want to override defaults.
The default port is `1080`, `authentication` has been disabled` by default.

## Start
```php service.php start -d```

## Stop
```php service.php stop```

## Status
```php service.php status```
10 changes: 10 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name" : "yuseferi/telegram-php-socks5",
"type" : "project",
"keywords": ["php-socks5","telegram socks5","php","telegram php socks5","easy proxy for telegram"],
"homepage": "http://www.github.com/yuseferi/telegram-php-socks5",
"license" : "MIT",
"require": {
"workerman/workerman" : ">=4.0.0"
}
}
6 changes: 6 additions & 0 deletions config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
// default variables that you can change based on your requirement
$AUTH_ENABLED = false;
$USERNAME = 'user';
$PASSWORD = 'password';
$PORT = 1080;
161 changes: 161 additions & 0 deletions service.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php
use \Workerman\Worker;
use \Workerman\WebServer;
use \Workerman\Connection\TcpConnection;
use \Workerman\Connection\AsyncTcpConnection;

// autoload class
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/config.php';

define('STAGE_INIT', 0);
define('STAGE_AUTH', 1);
define('STAGE_ADDR', 2);
define('STAGE_UDP_ASSOC', 3);
define('STAGE_DNS', 4);
define('STAGE_CONNECTING', 5);
define('STAGE_STREAM', 6);
define('STAGE_DESTROYED', -1);

define('CMD_CONNECT', 1);
define('CMD_BIND', 2);
define('CMD_UDP_ASSOCIATE', 3);

define('ADDRTYPE_IPV4', 1);
define('ADDRTYPE_IPV6', 4);
define('ADDRTYPE_HOST', 3);

define('METHOD_NO_AUTH', 0);
define('METHOD_GSSAPI', 1);
define('METHOD_USER_PASS', 2);

$worker = new Worker('tcp://0.0.0.0:'.$PORT);
$worker->onConnect = function($connection)
{
$connection->stage = STAGE_INIT;
};
$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("\x01\x00");
$connection->stage = STAGE_ADDR;
return;
}
echo "auth failed\n";
$connection->send("\x01\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;
}
$header_data = parse_socket5_header($buffer);
if(!$header_data)
{
$connection->close();
return;
}
$connection->stage = STAGE_CONNECTING;
$remote_connection = new AsyncTcpConnection('tcp://'.$header_data[1].':'.$header_data[2]);
$remote_connection->onConnect = function($remote_connection)use($connection)
{
$connection->state = STAGE_STREAM;
$connection->send("\x05\x00\x00\x01\x00\x00\x00\x00\x10\x10");
$connection->pipe($remote_connection);
$remote_connection->pipe($connection);
};
$remote_connection->connect();
}
};


function parse_socket5_header($buffer)
{
$addr_type = ord($buffer[3]);
switch($addr_type)
{
case ADDRTYPE_IPV4:
if(strlen($buffer) < 10)
{
echo bin2hex($buffer)."\n";
echo "buffer too short\n";
return false;
}
$dest_addr = ord($buffer[4]).'.'.ord($buffer[5]).'.'.ord($buffer[6]).'.'.ord($buffer[7]);
$port_data = unpack('n', substr($buffer, -2));
$dest_port = $port_data[1];
$header_length = 10;
break;
case ADDRTYPE_HOST:
$addrlen = ord($buffer[4]);
if(strlen($buffer) < $addrlen + 5)
{
echo $buffer."\n";
echo bin2hex($buffer)."\n";
echo "buffer too short\n";
return false;
}
$dest_addr = substr($buffer, 5, $addrlen);
$port_data = unpack('n', substr($buffer, -2));
$dest_port = $port_data[1];
$header_length = $addrlen + 7;
break;
case ADDRTYPE_IPV6:
if(strlen($buffer) < 22)
{
echo "buffer too short\n";
return false;
}
echo "todo ipv6\n";
return false;
default:
echo "unsupported addrtype $addr_type\n";
return false;
}
return array($addr_type, $dest_addr, $dest_port, $header_length);
}

// If it is not started in the root directory, run the runAll method

if(!defined('GLOBAL_START'))
{
Worker::runAll();
}

0 comments on commit 5d034c0

Please sign in to comment.