]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - extlib/HTTP/Request2/SOCKS5.php
PEAR::HTTP_Request2 updated to 2.2.1
[quix0rs-gnu-social.git] / extlib / HTTP / Request2 / SOCKS5.php
1 <?php\r
2 /**\r
3  * SOCKS5 proxy connection class\r
4  *\r
5  * PHP version 5\r
6  *\r
7  * LICENSE\r
8  *\r
9  * This source file is subject to BSD 3-Clause License that is bundled\r
10  * with this package in the file LICENSE and available at the URL\r
11  * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE\r
12  *\r
13  * @category  HTTP\r
14  * @package   HTTP_Request2\r
15  * @author    Alexey Borzov <avb@php.net>\r
16  * @copyright 2008-2014 Alexey Borzov <avb@php.net>\r
17  * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License\r
18  * @link      http://pear.php.net/package/HTTP_Request2\r
19  */\r
20 \r
21 /** Socket wrapper class used by Socket Adapter */\r
22 require_once 'HTTP/Request2/SocketWrapper.php';\r
23 \r
24 /**\r
25  * SOCKS5 proxy connection class (used by Socket Adapter)\r
26  *\r
27  * @category HTTP\r
28  * @package  HTTP_Request2\r
29  * @author   Alexey Borzov <avb@php.net>\r
30  * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License\r
31  * @version  Release: 2.2.1\r
32  * @link     http://pear.php.net/package/HTTP_Request2\r
33  * @link     http://pear.php.net/bugs/bug.php?id=19332\r
34  * @link     http://tools.ietf.org/html/rfc1928\r
35  */\r
36 class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper\r
37 {\r
38     /**\r
39      * Constructor, tries to connect and authenticate to a SOCKS5 proxy\r
40      *\r
41      * @param string $address        Proxy address, e.g. 'tcp://localhost:1080'\r
42      * @param int    $timeout        Connection timeout (seconds)\r
43      * @param array  $contextOptions Stream context options\r
44      * @param string $username       Proxy user name\r
45      * @param string $password       Proxy password\r
46      *\r
47      * @throws HTTP_Request2_LogicException\r
48      * @throws HTTP_Request2_ConnectionException\r
49      * @throws HTTP_Request2_MessageException\r
50      */\r
51     public function __construct(\r
52         $address, $timeout = 10, array $contextOptions = array(),\r
53         $username = null, $password = null\r
54     ) {\r
55         parent::__construct($address, $timeout, $contextOptions);\r
56 \r
57         if (strlen($username)) {\r
58             $request = pack('C4', 5, 2, 0, 2);\r
59         } else {\r
60             $request = pack('C3', 5, 1, 0);\r
61         }\r
62         $this->write($request);\r
63         $response = unpack('Cversion/Cmethod', $this->read(3));\r
64         if (5 != $response['version']) {\r
65             throw new HTTP_Request2_MessageException(\r
66                 'Invalid version received from SOCKS5 proxy: ' . $response['version'],\r
67                 HTTP_Request2_Exception::MALFORMED_RESPONSE\r
68             );\r
69         }\r
70         switch ($response['method']) {\r
71         case 2:\r
72             $this->performAuthentication($username, $password);\r
73         case 0:\r
74             break;\r
75         default:\r
76             throw new HTTP_Request2_ConnectionException(\r
77                 "Connection rejected by proxy due to unsupported auth method"\r
78             );\r
79         }\r
80     }\r
81 \r
82     /**\r
83      * Performs username/password authentication for SOCKS5\r
84      *\r
85      * @param string $username Proxy user name\r
86      * @param string $password Proxy password\r
87      *\r
88      * @throws HTTP_Request2_ConnectionException\r
89      * @throws HTTP_Request2_MessageException\r
90      * @link http://tools.ietf.org/html/rfc1929\r
91      */\r
92     protected function performAuthentication($username, $password)\r
93     {\r
94         $request  = pack('C2', 1, strlen($username)) . $username\r
95                     . pack('C', strlen($password)) . $password;\r
96 \r
97         $this->write($request);\r
98         $response = unpack('Cvn/Cstatus', $this->read(3));\r
99         if (1 != $response['vn'] || 0 != $response['status']) {\r
100             throw new HTTP_Request2_ConnectionException(\r
101                 'Connection rejected by proxy due to invalid username and/or password'\r
102             );\r
103         }\r
104     }\r
105 \r
106     /**\r
107      * Connects to a remote host via proxy\r
108      *\r
109      * @param string $remoteHost Remote host\r
110      * @param int    $remotePort Remote port\r
111      *\r
112      * @throws HTTP_Request2_ConnectionException\r
113      * @throws HTTP_Request2_MessageException\r
114      */\r
115     public function connect($remoteHost, $remotePort)\r
116     {\r
117         $request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost))\r
118                    . $remoteHost . pack('n', $remotePort);\r
119 \r
120         $this->write($request);\r
121         $response = unpack('Cversion/Creply/Creserved', $this->read(1024));\r
122         if (5 != $response['version'] || 0 != $response['reserved']) {\r
123             throw new HTTP_Request2_MessageException(\r
124                 'Invalid response received from SOCKS5 proxy',\r
125                 HTTP_Request2_Exception::MALFORMED_RESPONSE\r
126             );\r
127         } elseif (0 != $response['reply']) {\r
128             throw new HTTP_Request2_ConnectionException(\r
129                 "Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy",\r
130                 0, $response['reply']\r
131             );\r
132         }\r
133     }\r
134 }\r
135 ?>