Пример #1
0
 public function proxify(\Erebot\URIInterface $proxyURI, \Erebot\URIInterface $nextURI)
 {
     $credentials = $proxyURI->getUserInfo();
     $host = $nextURI->getHost();
     $port = $nextURI->getPort();
     $scheme = $nextURI->getScheme();
     if ($port === null) {
         $port = getservbyname($scheme, 'tcp');
     }
     if (!is_int($port) || $port <= 0 || $port > 65535) {
         throw new \Erebot\InvalidValueException('Invalid port');
     }
     $request = "";
     $request .= sprintf("CONNECT %s:%d HTTP/1.0\r\n", $host, $port);
     $request .= sprintf("Host: %s:%d\r\n", $host, $port);
     $request .= "User-Agent: Erebot/dev-master\r\n";
     if ($credentials !== null) {
         $request .= sprintf("Proxy-Authorization: basic %s\r\n", base64_encode($credentials));
     }
     $request .= "\r\n";
     for ($written = 0, $len = strlen($request); $written < $len; $written += $fwrite) {
         $fwrite = fwrite($this->_socket, substr($request, $written));
         if ($fwrite === false) {
             throw new \Erebot\Exception('Connection closed by proxy');
         }
     }
     $line = stream_get_line($this->_socket, 4096, "\r\n");
     if ($line === false) {
         throw new \Erebot\InvalidValueException('Invalid response from proxy');
     }
     $this->_logger->debug('%(line)s', array('line' => addcslashes($line, "..")));
     $contents = array_filter(explode(" ", $line));
     switch ((int) $contents[1]) {
         case 200:
             break;
         case 407:
             throw new \Erebot\Exception('Proxy authentication required');
         default:
             throw new \Erebot\Exception('Connection rejected by proxy');
     }
     // Avoid an endless loop by limiting the number of headers.
     // No HTTP server is likely to send more than 2^10 headers anyway.
     $max = 1 << 10;
     for ($i = 0; $i < $max; $i++) {
         $line = stream_get_line($this->_socket, 4096, "\r\n");
         if ($line === false) {
             throw new \Erebot\InvalidValueException('Invalid response from proxy');
         }
         if ($line == "") {
             break;
         }
         $this->_logger->debug('%(line)s', array('line' => addcslashes($line, "..")));
     }
     if ($i === $max) {
         throw new \Erebot\InvalidValueException('Endless loop detected in proxy response');
     }
 }
Пример #2
0
 /**
  * Does the authentication step.
  *
  * \param Erebot::URIInterface $proxyURI
  *      An object representing the URI of this SOCKS proxy server,
  *      containing the credentials that will be sent during the
  *      authentication step.
  */
 protected function userpass(\Erebot\URIInterface $proxyURI)
 {
     $username = $proxyURI->asParsedURL(PHP_URL_USER);
     $password = $proxyURI->asParsedURL(PHP_URL_PASS);
     if ($username === null || $password === null) {
         throw new \Erebot\InvalidValueException('No username or password supplied');
     }
     $ulen = strlen($username);
     $plen = strlen($password);
     if ($ulen > 255) {
         throw new \Erebot\InvalidValueException('Username too long (max. 255)');
     }
     if ($plen > 255) {
         throw new \Erebot\InvalidValueException('Password too long (max. 255)');
     }
     $this->write("" . pack("Ca*Ca*", $ulen, $username, $plen, $password));
     $line = $this->read(2);
     if ($line[0] != "") {
         throw new \Erebot\InvalidValueException('Bad subnegociation version');
     }
     if ($line[1] != "") {
         throw new \Erebot\InvalidValueException('Bad username or password');
     }
 }