ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > PHP, PERL, MySQL, JavaScript
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Ходим в php через socks4/5
  #1  
Старый 31.12.2007, 21:09
Аватар для h0d
h0d
Новичок
Регистрация: 31.12.2007
Сообщений: 3
Провел на форуме:
2242

Репутация: 15
По умолчанию Ходим в php через socks4/5

Класс сокета с поддержкой socks4/5-прокси
фичи:
- полная поддержка сокс4/5-прокси
- автоопределение типа прокси


вспомогательный класс (socket.class.php)
от этого класса идет наследование класса с поддержкой соксов

socket.class.php
PHP код:
/**
 * Socket Class

 * @author  hodik <icq://664679>
 * @package Classes
 * @subpackage network
 * @version 1.0
 * @filesource
 */

/**
 * CSocket

 * @package Classes
 * @subpackage network
 */ 

class CSocket{
    
/**
      * @desc
      * @access private
      */
    
var $_persistent false;
    
    
/**
      * @desc
      * @access private
      */
    
var $_connected false;
    
    
/**
      * @desc
      * @access private
      */
    
var $_conn null;
    
    
/**
      * Конструктор класса
      * @param boolean постоянное соединение или нет
      * @return void
      */
    
function CSocket($persistent false)
    {
        
$this->_persistent $persistent;
    }
    
    
/**
      * Проверяет, установлено ли соединение
      * @return boolean
      */
    
function _valid()
    {
        return 
is_resource($this->_conn) && ($this->_connected == true);
    }
    
    
/**
      * Устанавливает соединение
      * @param string
      * @param int
      * @return bool
      */
    
function connect($url$timeout 10)
    {
        
$host     parse_url($urlPHP_URL_HOST);
        if(!
$port parse_url($urlPHP_URL_PORT)) $port 80;
        
        
$sockFunc    = ($this->_persistent) ? "pfsockopen" "fsockopen";
        
$this->_conn $sockFunc($host$port$errno$errstr$timeout);
        
        if(!
$this->_conn)
        {
            
trigger_error("Couldn't connect to $host:$port"E_USER_WARNING);
            return 
false;
        }
        
        
$this->_connected true;
        return 
true;
    }
    
    
/**
      * Посылает данные (binary-safe)
      * @param какие-то данные
      * @return boolean
      */
    
function send($data)
    {
        if(!
$this->_valid())
        {
            
trigger_error("Error on sending data. Reason: Not connected"E_USER_WARNING);
            return 
false;
        }
        
        if(
fputs($this->_conn$data) === FALSE)
        {
            
trigger_error("Error on sending data to the server"E_USER_WARNING);
            return 
false;
        }
        return 
true;
    }
    
    
/**
      * Читает из входного потока определенное количество символов
      * @param int
      * @return string
      */
    
function read($len)
    {
        if(!
$this->_valid())
        {
            
trigger_error("Error on reading data. Reason: Not connected"E_USER_WARNING);
            return 
false;
        }

        if((
$buf fgets($this->_conn$len)) === FALSE)
        {
            
trigger_error("Error on reading data. Reason: Connection error"E_USER_WARNING);
            return 
false;
        }
        return 
$buf;
    }
    
    
/**
      * Читает строку из входного потока
      * @return string
      */
    
function readString()
    {
        if(!
$this->_valid())
        {
            
trigger_error("Error on reading string. Reason: Not connected"E_USER_WARNING);
            return 
false;
        }
        
        
$str null
        while(!
feof($this->_conn))
        {
            if((
$buf fgets($this->_conn128)) === FALSE)
            {
                
trigger_error("Error on reading string. Reason: Connection error"E_USER_WARNING);
                return 
false;
            }
            
            
$str .= $buf;
            if(
strlen($str) >= && (substr($str, -2) == "\r\n" || substr($str, -1) == "\n"))
            {
                return 
rtrim($str);
            }
        }
        
        if(
$str) return $str; else return false;
    }
    
    
/**
      * Читает все данные из входного потока
      * @return string
      */
    
function readAll()
    {
        if(!
$this->_valid())
        {
            
trigger_error("Error on reading data. Reason: Not connected"E_USER_WARNING);
            return 
false;
        }

        
$str "";
        while(!
feof($this->_conn))
        {
            if((
$buf fgets($this->_conn128)) === FALSE)
            {
                
trigger_error("Error on reading data. Reason: Connection error"E_USER_WARNING);
                return 
false;            
            }
            
$str .= $buf;
        }
        return 
$str;
    }
    
    
/**
      * Проверяет, активно ли соединение
      * @return boolean
      */
    
function isActive()
    {
        return 
$this->_valid();
    }
    
    
/**
      * Разрывает соединение
      * @return boolean
      */
    
function disconnect()
    {
        if(!
$this->_valid())
        {
            
trigger_error("Error on disconnecting. Reason: Not connected"E_USER_WARNING);
            return 
false;
        }
        
        
$this->_connected false;
        
fclose($this->_conn);
        return 
true;
    }
}
?> 
собсно сам класс для соксов
(socks.class.php)


PHP код:
<?
/**
 * Socket Class Through SOCKS4/5 proxy

 * @author hodik <icq://664679>
 * @package Classes
 * @subpackage network
 * @version 1.0
 * @filesource
 */

/**
 * CSocksSocket

 * @package Classes
 * @subpackage network
 */ 

require_once("socket.class.php");
define("SOCKS4_TYPE"1);
define("SOCKS5_TYPE"2);
define("AUTOMATIC_TYPE"3);

class 
CSocksSocket extends CSocket{
    
/**
      * @desc
      * @access private
      */
    
var $_proxyHost;
    
    
/**
      * @desc
      * @access private
      */    
    
var $_proxyPort;
    
    
/**
      * @desc
      * @access private
      */
    
var $_proxyType;

    
/**
      * @desc
      * @access private
      */
    
var $_proxyUser;

    
/**
      * @desc
      * @access private
      */
    
var $_proxyPwd;
    
    
/**
      * @desc
      * @access private
      */
    
var $_host;
    
    
/**
      * @desc
      * @access private
      */
    
var $_port;

    
/**
      * @desc
      * @access private
      */
    
var $_timeout;
    
    
/**
      * Устанавливает прокси и его тип
      * @param string
      * @return void
      */
    
function setProxy($proxyURL)
    {
        
$this->_proxyHost parse_url($proxyURLPHP_URL_HOST);
        
$this->_proxyPort parse_url($proxyURLPHP_URL_PORT);
        
$this->_proxyUser parse_url($proxyURLPHP_URL_USER);
        
$this->_proxyPwd  parse_url($proxyURLPHP_URL_PASS);
        
$this->_proxyType strtolower(parse_url($proxyURLPHP_URL_SCHEME));
    }
    
    
/**
      * Преобразует имя хоста или его адрес в число (4 байта)
      * @param string
      * @return int
      * @access private
      */
    
function _host2int($host)
    {
        
$ip gethostbyname($host);
        if(
preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/"$ip$matches))
        {
            
$retVal pack("C4"$matches[1], $matches[2], $matches[3], $matches[4]);
        }
        return 
$retVal;
    }
    
    
/** 
      * Соединяется через socks4
      * @access private
      * @return boolean
      */
    
function _connectThroughSocks4()
    {
        
$query  pack("C2"0x040x01); //VN, CD
        
$query .= pack("n"$this->_port); //DSTPORT
        
$query .= $this->_host2int($this->_host); //DSTIP
        
$query .= ($this->_proxyUser != "")? $this->_proxyUser "0"//IDENTD
        
$query .= pack("C"0); //NULL
        
        
if(!$this->send($query)) return false;
        if((
$response $this->read(9)) === false) return false;
        
        
$answer   unpack("Cvn/Ccd"substr($response02));
        
        
//по протоколу vn всегда должен быть 0
        
if($answer["vn"] != 0)
        {
            
trigger_error("The VN field of proxy server response is not zero. It should be 0"E_USER_WARNING);
            return 
false;
        }
        
        switch(
$answer["cd"])
        {
            case 
90:
                return 
true;
                break;
            case 
91:
            case 
92:
            case 
93:
                
trigger_error("Request to proxy have been rejected or failed"E_USER_WARNING);
                return 
false;
                break;
            default:
                
trigger_error("Unknow response from proxy"E_USER_WARNING);
                return 
false;
                break;
        }
        return 
false;
    }
    
    
/**
      * Выполняет аутентификацию логин/пароль по протоколу SOCKS5
      * @access private
      * @return boolean
      */
    
function _doSOCKS5Auth()
    {
        
$request  pack("C"1); //VN
        
$request .= pack("C"strlen($this->_proxyUser));
        
$request .= $this->_proxyUser;
        
$request .= pack("C"strlen($this->_proxyPwd));
        
$request .= $this->_proxyPwd;
        
        if(!
$this->send($request)) return false;
        if((
$response $this->read(3)) === false) return false;
        
        
$answer unpack("Cvn/Cresult"$response);
        if(
$answer["vn"] != && $answer["result"] != 0)
        {
            
trigger_error("Proxy have rejected the connection. Reason: Invalid username or/and password"E_USER_WARNING);
            return 
false;
        }
        return 
true;
    }
    
    
/**
      * Соединяется через socks5
      * @access private
      * @return boolean
      */
    
function _connectThroughSocks5()
    {
        
//выбор тип аутентификации
        
if($this->_proxyUser)
        {
            
$request pack("C4"5//версия сокс-протокола
                                  
2//длина
                                  
0//без аутентификации
                                  
2);//логин и пароль
        
}
        else
        {
            
$request pack("C3"510); //без аутентификации
        
}
        
        if(!
$this->send($request)) return false;
        if((
$response $this->read(3)) === false) return false;

        
$answer   unpack("Cver/Cmethod"$response);

        
//аутентификация: логин и пароль
        
if($answer["method"] == && !$this->_doSOCKS5Auth()) return false;
        
//без аутентификации
        
elseif($answer["method"] == 0) { /* ничего не делаем*/ }
        else 
        {
            
trigger_error("Proxy have rejected the connection. Reason: All the auth methods not supported"E_USER_WARNING);
            return 
false;
        }
        
        
//запрос CONNECT
        
$request  pack("C4"0x050x010x000x01); //VN=5,Method=1,Reserved=0,ATYP=ipv4
        
$request .= $this->_host2int($this->_host); //DSTIP
        
$request .= pack("n"$this->_port); //DSTPORT
        
        
if(!$this->send($request)) return false;
        if((
$response $this->read(11)) === false) return false//читаем ответ сервера

        
$answer   unpack("Cver/CREP"substr($response02));
        switch(
$answer["REP"])
        {
            case 
0:
                return 
true;
            default:
                
trigger_error("Proxy have rejected the connection. Reason: code error={$answer['REP']}"E_USER_WARNING);
                return 
false;
        }
    }
    
    
/**
      * Определяет тип прокси и соединяется
      * @return boolean
      */
    
function _connectAutoType()
    {
        
//попробуем как через сокс4, а вдруг получится
        
if($this->_connectThroughSocks4())
        {
            
$this->_proxyType "socks4";
            return 
true;
        }
        
//остался последний вариант: сокс5 (!!!)
        
else
        {
            
//на всякий случай разорвать соединение, а то сервер подумает, что над ним издеваются =)
            
$this->disconnect();
            if(!
parent::connect("{$this->_proxyHost}:{$this->_proxyPort}"$this->_timeout)) return false;
            if(
$this->_connectThroughSocks5())
            {
                
$this->_proxyType "socks5";
                return 
true;
            }
        }
        
        
//наверно это оказался SOCKS6, поддержку потом добавлю =)
        
return false;
    }
    
    
/**
      * Устанавливает соединение
      * @param string
      * @param int
      * @return boolean
      */
    
function connect($url$timeout 10)
    {
        
$this->_host     parse_url($urlPHP_URL_HOST);
        if(!
$this->_port parse_url($urlPHP_URL_PORT)) $this->_port 80;
        
$this->_timeout  $timeout;

        if(!
parent::connect("{$this->_proxyHost}:{$this->_proxyPort}"$this->_timeout)) return false;
        
        switch(
$this->_proxyType)
        {
            case 
"socks4";
                return 
$this->_connectThroughSocks4();
                break;
            case 
"socks5":
                return 
$this->_connectThroughSocks5();
                break;
            case 
"socks":
                return 
$this->_connectAutoType();
                break;
            default:
                return 
$this->_connectAutoType();
                break;
        }
    }
}
?>
пример использования:

PHP код:
<?
include("socks.class.php");

$sock = new CSocksSocket();
$sock->setProxy("socks://127.0.0.1:1080");//автоопределение
$sock->setProxy("socks4://127.0.0.1:1080"); //явно задан вид - сокс4
$sock->setProxy("socks5://127.0.0.1:1080"); //явно задан вид - сокс5
$sock->connect("yandex.ru:80"10); //10-это таймаут
$sock->send("GET / HTTP/1.0\r\nConnection: close\r\n\r\n");
print 
$sock->readAll();  
?>
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Books PHP FRAGNATIC PHP, PERL, MySQL, JavaScript 186 21.02.2010 02:41
Что такое Php? PAPA212 Болталка 13 28.12.2007 20:44
php через MySQL Grema PHP, PERL, MySQL, JavaScript 5 19.01.2006 17:23
Безопасность в Php, Часть Iii k00p3r Чужие Статьи 0 11.07.2005 19:02
Защищаем Php. Шаг за шагом. k00p3r Чужие Статьи 0 13.06.2005 11:31



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ