]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - extlib/HTTP/Request2/SOCKS5.php
Updating external libraries for net access
[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  * Copyright (c) 2008-2012, Alexey Borzov <avb@php.net>\r
10  * All rights reserved.\r
11  *\r
12  * Redistribution and use in source and binary forms, with or without\r
13  * modification, are permitted provided that the following conditions\r
14  * are met:\r
15  *\r
16  *    * Redistributions of source code must retain the above copyright\r
17  *      notice, this list of conditions and the following disclaimer.\r
18  *    * Redistributions in binary form must reproduce the above copyright\r
19  *      notice, this list of conditions and the following disclaimer in the\r
20  *      documentation and/or other materials provided with the distribution.\r
21  *    * The names of the authors may not be used to endorse or promote products\r
22  *      derived from this software without specific prior written permission.\r
23  *\r
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS\r
25  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
26  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
27  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
28  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
30  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
31  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\r
32  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
35  *\r
36  * @category HTTP\r
37  * @package  HTTP_Request2\r
38  * @author   Alexey Borzov <avb@php.net>\r
39  * @license  http://opensource.org/licenses/bsd-license.php New BSD License\r
40  * @version  SVN: $Id: SOCKS5.php 324953 2012-04-08 07:24:12Z avb $\r
41  * @link     http://pear.php.net/package/HTTP_Request2\r
42  */\r
43 \r
44 /** Socket wrapper class used by Socket Adapter */\r
45 require_once 'HTTP/Request2/SocketWrapper.php';\r
46 \r
47 /**\r
48  * SOCKS5 proxy connection class (used by Socket Adapter)\r
49  *\r
50  * @category HTTP\r
51  * @package  HTTP_Request2\r
52  * @author   Alexey Borzov <avb@php.net>\r
53  * @license  http://opensource.org/licenses/bsd-license.php New BSD License\r
54  * @version  Release: 2.1.1\r
55  * @link     http://pear.php.net/package/HTTP_Request2\r
56  * @link     http://pear.php.net/bugs/bug.php?id=19332\r
57  * @link     http://tools.ietf.org/html/rfc1928\r
58  */\r
59 class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper\r
60 {\r
61     /**\r
62      * Constructor, tries to connect and authenticate to a SOCKS5 proxy\r
63      *\r
64      * @param string $address    Proxy address, e.g. 'tcp://localhost:1080'\r
65      * @param int    $timeout    Connection timeout (seconds)\r
66      * @param array  $sslOptions SSL context options\r
67      * @param string $username   Proxy user name\r
68      * @param string $password   Proxy password\r
69      *\r
70      * @throws HTTP_Request2_LogicException\r
71      * @throws HTTP_Request2_ConnectionException\r
72      * @throws HTTP_Request2_MessageException\r
73      */\r
74     public function __construct(\r
75         $address, $timeout = 10, array $sslOptions = array(),\r
76         $username = null, $password = null\r
77     ) {\r
78         parent::__construct($address, $timeout, $sslOptions);\r
79 \r
80         if (strlen($username)) {\r
81             $request = pack('C4', 5, 2, 0, 2);\r
82         } else {\r
83             $request = pack('C3', 5, 1, 0);\r
84         }\r
85         $this->write($request);\r
86         $response = unpack('Cversion/Cmethod', $this->read(3));\r
87         if (5 != $response['version']) {\r
88             throw new HTTP_Request2_MessageException(\r
89                 'Invalid version received from SOCKS5 proxy: ' . $response['version'],\r
90                 HTTP_Request2_Exception::MALFORMED_RESPONSE\r
91             );\r
92         }\r
93         switch ($response['method']) {\r
94         case 2:\r
95             $this->performAuthentication($username, $password);\r
96         case 0:\r
97             break;\r
98         default:\r
99             throw new HTTP_Request2_ConnectionException(\r
100                 "Connection rejected by proxy due to unsupported auth method"\r
101             );\r
102         }\r
103     }\r
104 \r
105     /**\r
106      * Performs username/password authentication for SOCKS5\r
107      *\r
108      * @param string $username Proxy user name\r
109      * @param string $password Proxy password\r
110      *\r
111      * @throws HTTP_Request2_ConnectionException\r
112      * @throws HTTP_Request2_MessageException\r
113      * @link http://tools.ietf.org/html/rfc1929\r
114      */\r
115     protected function performAuthentication($username, $password)\r
116     {\r
117         $request  = pack('C2', 1, strlen($username)) . $username\r
118                     . pack('C', strlen($password)) . $password;\r
119 \r
120         $this->write($request);\r
121         $response = unpack('Cvn/Cstatus', $this->read(3));\r
122         if (1 != $response['vn'] || 0 != $response['status']) {\r
123             throw new HTTP_Request2_ConnectionException(\r
124                 'Connection rejected by proxy due to invalid username and/or password'\r
125             );\r
126         }\r
127     }\r
128 \r
129     /**\r
130      * Connects to a remote host via proxy\r
131      *\r
132      * @param string $remoteHost Remote host\r
133      * @param int    $remotePort Remote port\r
134      *\r
135      * @throws HTTP_Request2_ConnectionException\r
136      * @throws HTTP_Request2_MessageException\r
137      */\r
138     public function connect($remoteHost, $remotePort)\r
139     {\r
140         $request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost))\r
141                    . $remoteHost . pack('n', $remotePort);\r
142 \r
143         $this->write($request);\r
144         $response = unpack('Cversion/Creply/Creserved', $this->read(1024));\r
145         if (5 != $response['version'] || 0 != $response['reserved']) {\r
146             throw new HTTP_Request2_MessageException(\r
147                 'Invalid response received from SOCKS5 proxy',\r
148                 HTTP_Request2_Exception::MALFORMED_RESPONSE\r
149             );\r
150         } elseif (0 != $response['reply']) {\r
151             throw new HTTP_Request2_ConnectionException(\r
152                 "Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy",\r
153                 0, $response['reply']\r
154             );\r
155         }\r
156     }\r
157 }\r
158 ?>