Example #1
0
 /**
  * Import
  * @param  mixed $id ID
  * @return mixed
  */
 public static function import($id)
 {
     if ($id instanceof static) {
         return $id;
     } elseif ($id instanceof \MongoId) {
         $id = (string) $id;
     } elseif (!is_string($id)) {
         if (is_array($id) && isset($id['$id'])) {
             return static::import($id['$id']);
         }
         return false;
     } elseif (mb_orig_strlen($id) === 24) {
         if (!ctype_xdigit($id)) {
             return false;
         }
     } elseif (ctype_alnum($id)) {
         $id = gmp_strval(gmp_init(strrev($id), 62), 16);
         if (mb_orig_strlen($id) > 24) {
             return false;
         }
         if (mb_orig_strlen($id) < 24) {
             $id = str_pad($id, 24, '0', STR_PAD_LEFT);
         }
     } else {
         return false;
     }
     return new static($id);
 }
Example #2
0
 /**
  * @TODO DESCR
  * @param $p
  */
 public function sendPacket($p)
 {
     if ($p === null) {
         return;
     }
     $data = \igbinary_serialize($p);
     $this->write(pack('N', mb_orig_strlen($data)) . $data);
 }
Example #3
0
 /**
  * Build checksum
  * @param  string $data Source
  * @return string       Checksum
  */
 protected static function checksum($data)
 {
     $bit = unpack('n*', $data);
     $sum = array_sum($bit);
     if (mb_orig_strlen($data) % 2) {
         $temp = unpack('C*', $data[mb_orig_strlen($data) - 1]);
         $sum += $temp[1];
     }
     $sum = ($sum >> 16) + ($sum & 0xffff);
     $sum += $sum >> 16;
     return pack('n*', ~$sum);
 }
Example #4
0
 /**
  * Magic __call
  * Example:
  * $gibson->set(3600, 'key', 'value');
  * $gibson->get('key', function ($conn) {...});
  * @param  string $name Command name
  * @param  array $args Arguments
  * @return void
  */
 public function __call($name, $args)
 {
     $name = strtolower($name);
     $onResponse = null;
     if (($e = end($args)) && (is_array($e) || is_object($e)) && is_callable($e)) {
         $onResponse = array_pop($args);
     }
     if (!isset($this->opCodes[$name])) {
         throw new UndefinedMethodCalled();
     }
     $data = implode(" ", $args);
     $this->requestByServer(null, pack('LS', mb_orig_strlen($data) + 2, $this->opCodes[$name]) . $data, $onResponse);
 }
Example #5
0
function compareStrings($expected, $actual)
{
    if (function_exists('mb_orig_strlen')) {
        $lenExpected = mb_orig_strlen($expected);
        $lenActual = mb_orig_strlen($actual);
    } else {
        $lenExpected = strlen($expected);
        $lenActual = strlen($actual);
    }
    $status = $lenExpected ^ $lenActual;
    $len = min($lenExpected, $lenActual);
    for ($i = 0; $i < $len; $i++) {
        $status |= ord($expected[$i]) ^ ord($actual[$i]);
    }
    return $status === 0;
}
Example #6
0
 /**
  * Extract key and value pair from line.
  * @param  string $line
  * @return array
  */
 public static function extract($line)
 {
     $e = explode(': ', $line, 2);
     $header = strtolower(trim($e[0]));
     $value = isset($e[1]) ? trim($e[1]) : null;
     $safe = false;
     foreach (self::$safeCaseValues as $item) {
         if (strncasecmp($header, $item, mb_orig_strlen($item)) === 0) {
             $safe = true;
             break;
         }
         if (strncasecmp($value, $item, mb_orig_strlen($item)) === 0) {
             $safe = true;
             break;
         }
     }
     if (!$safe) {
         $value = strtolower($value);
     }
     return [$header, $value];
 }
Example #7
0
 /**
  * A timing safe comparison method.
  *
  * C function memcmp() internally used by PHP, exits as soon as a difference
  * is found in the two buffers. That makes possible of leaking
  * timing information useful to an attacker attempting to iteratively guess
  * the unknown string (e.g. password).
  *
  * @param string $expected
  * @param string $actual
  * @throws \Freetrix\Main\ArgumentTypeException
  * @return bool
  */
 protected function compareStrings($expected, $actual)
 {
     if (!is_string($expected)) {
         throw new ArgumentTypeException('expected', 'string');
     }
     if (!is_string($actual)) {
         throw new ArgumentTypeException('actual', 'string');
     }
     if (function_exists('mb_orig_strlen')) {
         $lenExpected = mb_orig_strlen($expected);
         $lenActual = mb_orig_strlen($actual);
     } else {
         $lenExpected = strlen($expected);
         $lenActual = strlen($actual);
     }
     $status = $lenExpected ^ $lenActual;
     $len = min($lenExpected, $lenActual);
     for ($i = 0; $i < $len; $i++) {
         $status |= ord($expected[$i]) ^ ord($actual[$i]);
     }
     return $status === 0;
 }
Example #8
0
    /**
     * Constructor
     * @return void
     */
    public function init()
    {
        parent::init();
        if (isset($this->attrs->version)) {
            $this->version = $this->attrs->version;
        }
        $this->header('Cache-Control: max-age=31536000, public, pre-check=0, post-check=0');
        $this->header('Expires: ' . date('r', strtotime('+1 year')));
        $html = '<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<script>
		document.domain = document.domain;
		_sockjs_onload = function(){SockJS.bootstrap_iframe();};
	</script>
	<script src="https://cdn.jsdelivr.net/sockjs/' . htmlentities($this->version, ENT_QUOTES, 'UTF-8') . '/sockjs.min.js"></script>
</head>
<body>
	<h2>Don\'t panic!</h2>
	<p>This is a SockJS hidden iframe. It\'s used for cross domain magic.</p>
</body>
</html>';
        $etag = 'W/"' . sha1($html) . '"';
        $this->header('ETag: ' . $etag);
        if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
            if ($_SERVER['HTTP_IF_NONE_MATCH'] === $etag) {
                $this->status(304);
                $this->removeHeader('Content-Type');
                $this->finish();
                return;
            }
        }
        $this->header('Content-Length: ' . mb_orig_strlen($html));
        echo $html;
        $this->finish();
    }
Example #9
0
 function strlen($s)
 {
     if (function_exists('mb_orig_strlen')) {
         return mb_orig_strlen($s);
     }
     return strlen($s);
 }
Example #10
0
 /**
  * Draw a table
  * @param  array Array of table's rows
  * @return void
  */
 public function drawTable($rows)
 {
     $pad = [];
     foreach ($rows as $row) {
         foreach ($row as $k => $v) {
             if (substr($k, 0, 1) === '_') {
                 continue;
             }
             if (!isset($pad[$k]) || strlen($v) > $pad[$k]) {
                 $pad[$k] = mb_orig_strlen($v);
             }
         }
     }
     foreach ($rows as $row) {
         if (isset($row['_color'])) {
             $this->setStyle($row['_color']);
         }
         if (isset($row['_bold'])) {
             $this->setStyle('1');
         }
         if (isset($row['_'])) {
             echo $row['_'];
         } else {
             $i = 0;
             foreach ($row as $k => $v) {
                 if (substr($k, 0, 1) === '_') {
                     continue;
                 }
                 if ($i > 0) {
                     echo "\t";
                 }
                 echo str_pad($v, $pad[$k]);
                 ++$i;
             }
         }
         $this->resetStyle();
         echo "\n";
     }
 }
Example #11
0
 /**
  * @TODO DESCR
  */
 public function createXMLStream()
 {
     $this->xml = new XMLStream();
     $this->xml->setDefaultNS('jabber:client');
     $this->xml->addXPathHandler('{http://etherx.jabber.org/streams}features', function ($xml) {
         /** @var XMLStream $xml */
         if ($xml->hasSub('starttls') and $this->use_encryption) {
             $this->sendXML("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required /></starttls>");
         } elseif ($xml->hasSub('bind') and $this->authorized) {
             $id = $this->getId();
             $this->iqSet('<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>' . $this->path . '</resource></bind>', function ($xml) {
                 if ($xml->attrs['type'] === 'result') {
                     $this->fulljid = $xml->sub('bind')->sub('jid')->data;
                     $jidarray = explode('/', $this->fulljid);
                     $this->jid = $jidarray[0];
                 }
                 $this->iqSet('<session xmlns="urn:ietf:params:xml:ns:xmpp-session" />', function ($xml) {
                     $this->roster = new XMPPRoster($this);
                     if ($this->onConnected) {
                         $this->connected = true;
                         $this->onConnected->executeAll($this);
                         $this->onConnected = null;
                     }
                     $this->event('connected');
                 });
             });
         } else {
             if (mb_orig_strlen($this->password)) {
                 $this->sendXML("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" . base64_encode("" . $this->user . "" . $this->password) . "</auth>");
             } else {
                 $this->sendXML("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>");
             }
         }
     });
     $this->xml->addXPathHandler('{urn:ietf:params:xml:ns:xmpp-sasl}success', function ($xml) {
         $this->authorized = true;
         $this->xml->finish();
         $this->createXMLStream();
         $this->startXMLStream();
     });
     $this->xml->addXPathHandler('{urn:ietf:params:xml:ns:xmpp-sasl}failure', function ($xml) {
         if ($this->onConnected) {
             $this->connected = false;
             $func = $this->onConnected;
             $func($this);
             $this->onConnected = null;
         }
         $this->finish();
     });
     $this->xml->addXPathHandler('{urn:ietf:params:xml:ns:xmpp-tls}proceed', function ($xml) {
         Daemon::log("XMPPClient: TLS not supported.");
     });
     $this->xml->addXPathHandler('{jabber:client}message', function ($xml) {
         if (isset($xml->attrs['type'])) {
             $payload['type'] = $xml->attrs['type'];
         } else {
             $payload['type'] = 'chat';
         }
         $payload['xml'] = $xml;
         $payload['from'] = $xml->attrs['from'];
         if ($xml->hasSub('body')) {
             $payload['body'] = $xml->sub('body')->data;
             $this->event('message', $payload);
         }
     });
 }
Example #12
0
 /**
  * Read from shared memory
  * @param  integer $offset Offset
  * @param  integer $length Length
  * @return string          Data
  */
 public function read($offset, $length = 1)
 {
     $ret = '';
     $segno = floor($offset / $this->segsize);
     $sOffset = $offset % $this->segsize;
     while (true) {
         if (!isset($this->segments[$segno])) {
             if (!$this->open($segno)) {
                 goto ret;
             }
         }
         $ret .= shmop_read($this->segments[$segno], $sOffset, min($length - mb_orig_strlen($ret), $this->segsize));
         if (mb_orig_strlen($ret) >= $length) {
             goto ret;
         }
         ++$segno;
         $sOffset = 0;
     }
     ret:
     return $ret === '' ? false : $ret;
 }
Example #13
0
 /**
  * Sends a chunk
  * @param  object $req Request
  * @param  string $chunk Data
  * @return bool
  */
 public function sendChunk($req, $chunk)
 {
     $packet = "" . "" . pack('nn', $req->attrs->id, mb_orig_strlen($chunk)) . "" . "";
     // reserved
     return $this->write($packet) && $this->write($chunk);
     // content
 }
Example #14
0
 public function _get_xml_chunk_mb_orig($fp)
 {
     if ($this->buf_position >= $this->buf_len) {
         if (!feof($fp)) {
             $this->buf = fread($fp, $this->read_size);
             $this->buf_position = 0;
             $this->buf_len = mb_orig_strlen($this->buf);
         } else {
             return false;
         }
     }
     //Skip line delimiters (ltrim)
     $xml_position = mb_orig_strpos($this->buf, "<", $this->buf_position);
     while ($xml_position === $this->buf_position) {
         $this->buf_position++;
         $this->file_position++;
         //Buffer ended with white space so we can refill it
         if ($this->buf_position >= $this->buf_len) {
             if (!feof($fp)) {
                 $this->buf = fread($fp, $this->read_size);
                 $this->buf_position = 0;
                 $this->buf_len = mb_orig_strlen($this->buf);
             } else {
                 return false;
             }
         }
         $xml_position = mb_orig_strpos($this->buf, "<", $this->buf_position);
     }
     //Let's find next line delimiter
     while ($xml_position === false) {
         $next_search = $this->buf_len;
         //Delimiter not in buffer so try to add more data to it
         if (!feof($fp)) {
             $this->buf .= fread($fp, $this->read_size);
             $this->buf_len = mb_orig_strlen($this->buf);
         } else {
             break;
         }
         //Let's find xml tag start
         $xml_position = mb_orig_strpos($this->buf, "<", $next_search);
     }
     if ($xml_position === false) {
         $xml_position = $this->buf_len + 1;
     }
     $len = $xml_position - $this->buf_position;
     $this->file_position += $len;
     $result = mb_orig_substr($this->buf, $this->buf_position, $len);
     $this->buf_position = $xml_position;
     return $result;
 }
Example #15
0
 /**
  * Apply mask
  * @param $data
  * @param string|false $mask
  * @return mixed
  */
 public function mask($data, $mask)
 {
     for ($i = 0, $l = mb_orig_strlen($data), $ml = mb_orig_strlen($mask); $i < $l; $i++) {
         $data[$i] = $data[$i] ^ $mask[$i % $ml];
     }
     return $data;
 }
Example #16
0
 /**
  * Returns the character at index $idx in $str in constant time
  * @param  string $str String
  * @param  integer $idx Index
  * @return string
  */
 public static function stringIdx($str, $idx)
 {
     // FIXME: Make the const-time hack below work for all integer sizes, or
     // check it properly
     $l = mb_orig_strlen($str);
     if ($l > 65535 || $idx > $l) {
         return false;
     }
     $r = 0;
     for ($i = 0; $i < $l; ++$i) {
         $x = $i ^ $idx;
         $mask = ((($x | $x >> 16) & 0xffff) + 0xffff >> 16) - 1;
         $r |= ord($str[$i]) & $mask;
     }
     return chr($r);
 }
Example #17
0
 /**
  * onRead
  * @return void
  */
 protected function onRead()
 {
     if (!$this->policyReqNotFound) {
         $d = $this->drainIfMatch("<policy-file-request/>");
         if ($d === null) {
             // partially match
             return;
         }
         if ($d) {
             $FP = \PHPDaemon\Servers\FlashPolicy\Pool::getInstance($this->pool->config->fpsname->value, false);
             if ($FP && $FP->policyData) {
                 $this->write($FP->policyData . "");
             }
             $this->finish();
             return;
         } else {
             $this->policyReqNotFound = true;
         }
     }
     start:
     if ($this->finished) {
         return;
     }
     if ($this->state === self::STATE_ROOT) {
         if ($this->req !== null) {
             // we have to wait the current request
             return;
         }
         if (!($this->req = $this->newRequest())) {
             $this->finish();
             return;
         }
         $this->state = self::STATE_FIRSTLINE;
     } else {
         if (!$this->req || $this->state === self::STATE_PROCESSING) {
             if (isset($this->bev) && $this->bev->input->length > 0) {
                 Daemon::log('Unexpected input (HTTP request, ' . $this->state . '): ' . json_encode($this->read($this->bev->input->length)));
             }
             return;
         }
     }
     if ($this->state === self::STATE_FIRSTLINE) {
         if (!$this->httpReadFirstline()) {
             return;
         }
         Timer::remove($this->keepaliveTimer);
         $this->state = self::STATE_HEADERS;
     }
     if ($this->state === self::STATE_HEADERS) {
         if (!$this->httpReadHeaders()) {
             return;
         }
         if (!$this->httpProcessHeaders()) {
             $this->finish();
             return;
         }
         $this->state = self::STATE_CONTENT;
     }
     if ($this->state === self::STATE_CONTENT) {
         if (!isset($this->req->attrs->input) || !$this->req->attrs->input) {
             $this->finish();
             return;
         }
         $this->req->attrs->input->readFromBuffer($this->bev->input);
         if (!$this->req->attrs->input->isEOF()) {
             return;
         }
         $this->state = self::STATE_PROCESSING;
         if ($this->freedBeforeProcessing) {
             $this->freeRequest($this->req);
             $this->freedBeforeProcessing = false;
             goto start;
         }
         $this->freezeInput();
         if ($this->req->attrs->inputDone && $this->req->attrs->paramsDone) {
             if ($this->pool->variablesOrder === null) {
                 $this->req->attrs->request = $this->req->attrs->get + $this->req->attrs->post + $this->req->attrs->cookie;
             } else {
                 for ($i = 0, $s = mb_orig_strlen($this->pool->variablesOrder); $i < $s; ++$i) {
                     $char = $this->pool->variablesOrder[$i];
                     if ($char === 'G') {
                         if (is_array($this->req->attrs->get)) {
                             $this->req->attrs->request += $this->req->attrs->get;
                         }
                     } elseif ($char === 'P') {
                         if (is_array($this->req->attrs->post)) {
                             $this->req->attrs->request += $this->req->attrs->post;
                         }
                     } elseif ($char === 'C') {
                         if (is_array($this->req->attrs->cookie)) {
                             $this->req->attrs->request += $this->req->attrs->cookie;
                         }
                     }
                 }
             }
             Daemon::$process->timeLastActivity = time();
         }
     }
 }
Example #18
0
 /**
  * Parses multipart
  * @return void
  */
 public function parseMultipart()
 {
     start:
     if ($this->frozen) {
         return;
     }
     if ($this->state === self::STATE_SEEKBOUNDARY) {
         // seek to the nearest boundary
         if (($p = $this->search('--' . $this->boundary . "\r\n")) === false) {
             return;
         }
         // we have found the nearest boundary at position $p
         if ($p > 0) {
             $extra = $this->read($p);
             if ($extra !== "\r\n") {
                 $this->log('parseBody(): SEEKBOUNDARY: got unexpected data before boundary (length = ' . $p . '): ' . Debug::exportBytes($extra));
             }
         }
         $this->drain(mb_orig_strlen($this->boundary) + 4);
         // drain
         $this->state = self::STATE_HEADERS;
     }
     if ($this->state === self::STATE_HEADERS) {
         // parse the part's headers
         $this->curPartDisp = false;
         $i = 0;
         do {
             $l = $this->readline(\EventBuffer::EOL_CRLF);
             if ($l === null) {
                 return;
             }
             if ($l === '') {
                 break;
             }
             $e = explode(':', $l, 2);
             $e[0] = strtr(strtoupper($e[0]), Generic::$htr);
             if (isset($e[1])) {
                 $e[1] = ltrim($e[1]);
             }
             if ($e[0] === 'CONTENT_DISPOSITION' && isset($e[1])) {
                 Generic::parseStr($e[1], $this->curPartDisp, true);
                 if (!isset($this->curPartDisp['form-data'])) {
                     break;
                 }
                 if (!isset($this->curPartDisp['name'])) {
                     break;
                 }
                 $this->curPartDisp['name'] = trim($this->curPartDisp['name'], '"');
                 $name = $this->curPartDisp['name'];
                 if (isset($this->curPartDisp['filename'])) {
                     $this->curPartDisp['filename'] = trim($this->curPartDisp['filename'], '"');
                     if (!ini_get('file_uploads')) {
                         break;
                     }
                     $this->req->attrs->files[$name] = ['name' => $this->curPartDisp['filename'], 'type' => '', 'tmp_name' => null, 'fp' => null, 'error' => UPLOAD_ERR_OK, 'size' => 0];
                     $this->curPart =& $this->req->attrs->files[$name];
                     $this->req->onUploadFileStart($this);
                     $this->state = self::STATE_UPLOAD;
                 } else {
                     $this->curPart =& $this->req->attrs->post[$name];
                     $this->curPart = '';
                 }
             } elseif ($e[0] === 'CONTENT_TYPE' && isset($e[1])) {
                 if (isset($this->curPartDisp['name']) && isset($this->curPartDisp['filename'])) {
                     $this->curPart['type'] = $e[1];
                 }
             }
         } while ($i++ < 10);
         if ($this->state === self::STATE_HEADERS) {
             $this->state = self::STATE_BODY;
         }
         goto start;
     }
     if ($this->state === self::STATE_BODY || $this->state === self::STATE_UPLOAD) {
         // process the body
         $chunkEnd1 = $this->search("\r\n--" . $this->boundary . "\r\n");
         $chunkEnd2 = $this->search("\r\n--" . $this->boundary . "--\r\n");
         if ($chunkEnd1 === false && $chunkEnd2 === false) {
             /*  we have only piece of Part in buffer */
             $l = $this->length - mb_orig_strlen($this->boundary) - 8;
             if ($l <= 0) {
                 return;
             }
             if ($this->state === self::STATE_BODY && isset($this->curPartDisp['name'])) {
                 $this->curPart .= $this->read($l);
             } elseif ($this->state === self::STATE_UPLOAD && isset($this->curPartDisp['filename'])) {
                 $this->curPart['size'] += $l;
                 if ($this->req->getUploadMaxSize() < $this->curPart['size']) {
                     $this->curPart['error'] = UPLOAD_ERR_INI_SIZE;
                     $this->req->header('413 Request Entity Too Large');
                     $this->req->out('');
                     $this->req->finish();
                 } elseif ($this->maxFileSize && $this->maxFileSize < $this->curPart['size']) {
                     $this->curPart['error'] = UPLOAD_ERR_FORM_SIZE;
                     $this->req->header('413 Request Entity Too Large');
                     $this->req->out('');
                     $this->req->finish();
                 } else {
                     $this->curChunkSize = $l;
                     $this->req->onUploadFileChunk($this);
                 }
             }
         } else {
             /* we have entire Part in buffer */
             if ($chunkEnd1 === false) {
                 $l = $chunkEnd2;
                 $endOfMsg = true;
             } else {
                 $l = $chunkEnd1;
                 $endOfMsg = false;
             }
             if ($this->state === self::STATE_BODY && isset($this->curPartDisp['name'])) {
                 $this->curPart .= $this->read($l);
                 if ($this->curPartDisp['name'] === 'MAX_FILE_SIZE') {
                     $this->maxFileSize = (int) $this->curPart;
                 }
             } elseif ($this->state === self::STATE_UPLOAD && isset($this->curPartDisp['filename'])) {
                 $this->curPart['size'] += $l;
                 $this->curChunkSize = $l;
                 $this->req->onUploadFileChunk($this, true);
             }
             $this->state = self::STATE_SEEKBOUNDARY;
             if ($endOfMsg) {
                 // end of whole message
                 $this->sendEOF();
             } else {
                 goto start;
                 // let's read the next part
             }
         }
     }
 }
Example #19
0
 /**
  * Send a command
  *
  * @param $commandName
  * @param $payload
  * @param callable $cb = null
  */
 public function sendCommand($commandName, $payload, $cb = null)
 {
     $pct = implode(static::ARGS_DELIMITER, array_map(function ($item) {
         return !is_scalar($item) ? serialize($item) : $item;
     }, (array) $payload));
     $this->onResponse->push($cb);
     $this->write(pack(static::HEADER_WRITE_FORMAT, static::MAGIC_REQUEST, $this->requestCommandList[$commandName], mb_orig_strlen($pct)));
     $this->write($pct);
 }
Example #20
0
 /**
  * Gets the host information
  * @param  string $hostname Hostname
  * @param  callable $cb Callback
  * @callback $cb ( )
  * @return void
  */
 public function get($hostname, $cb)
 {
     $this->onResponse->push($cb);
     $this->setFree(false);
     $e = explode(':', $hostname, 3);
     $hostname = $e[0];
     $qtype = isset($e[1]) ? $e[1] : 'A';
     $qclass = isset($e[2]) ? $e[2] : 'IN';
     $QD = [];
     $qtypeInt = array_search($qtype, Pool::$type, true);
     $qclassInt = array_search($qclass, Pool::$class, true);
     if ($qtypeInt === false || $qclassInt === false) {
         $cb(false);
         return;
     }
     $q = Binary::labels($hostname) . Binary::word($qtypeInt) . Binary::word($qclassInt);
     $QD[] = $q;
     $packet = Binary::word(++$this->seq) . Binary::bitmap2bytes('0' . '0000' . '0' . '0' . '1' . '0' . '000' . '0000', 2) . Binary::word(sizeof($QD)) . Binary::word(0) . Binary::word(0) . Binary::word(0) . implode('', $QD);
     if ($this->type === 'udp') {
         $this->write($packet);
     } else {
         $this->write(Binary::word(mb_orig_strlen($packet)) . $packet);
     }
 }
Example #21
0
 public function saslScrumSHA1Step($session, $input = null)
 {
     $session['step']++;
     $query = [];
     if (!is_null($input) && (!empty($input['$err']) || !empty($input['errmsg']))) {
         $session['cb']($input);
         return;
     }
     if ($session['step'] == 1) {
         $session['nonce'] = base64_encode(openssl_random_pseudo_bytes(24));
         $payload = 'n,,n=' . $session['user'] . ',r=' . $session['nonce'];
         $query = ['saslStart' => 1, 'mechanism' => 'SCRAM-SHA-1', 'payload' => base64_encode($payload)];
         $session['auth_message'] .= 'n=' . $session['user'] . ',r=' . $session['nonce'] . ',';
     } elseif ($session['step'] == 2) {
         $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
         $error = null;
         if (count($in_payload) != 3) {
             $error = 'Incorrect number of arguments for first SCRAM-SHA-1 server message, got ' . count($in_payload) . 'expected 3';
         } elseif (mb_orig_strlen($in_payload['r']) < 2) {
             $error = 'Incorrect SCRAM-SHA-1 client|server nonce: ' . $in_payload['r'];
         } elseif (mb_orig_strlen($in_payload['s']) < 6) {
             $error = 'Incorrect SCRAM-SHA-1 salt: ' . $in_payload['s'];
         } elseif (mb_orig_strlen($in_payload['i']) < 3) {
             $error = 'Incorrect SCRAM-SHA-1 iteration count: ' . $in_payload['i'];
         } elseif (mb_orig_strpos($in_payload['r'], $session['nonce']) !== 0) {
             $error = 'Server SCRAM-SHA-1 nonce does not match client nonce';
         }
         if (!empty($error)) {
             $session['cb'](['ok' => 0, 'errmsg' => $error]);
             return;
         } else {
             $session['conversation_id'] = $input['conversationId'];
             $session['nonce'] = $in_payload['r'];
         }
         $payload = 'c=biws,r=' . $session['nonce'];
         $session['auth_message'] .= base64_decode($input['payload']) . ',' . $payload;
         $decoded_salt = base64_decode($in_payload['s']);
         $password = md5($session['user'] . ':mongo:' . $session['password']);
         $salted_password = hash_pbkdf2('sha1', $password, $decoded_salt, (int) $in_payload['i'], 0, true);
         $client_key = hash_hmac('sha1', 'Client Key', $salted_password, true);
         $stored_key = sha1($client_key, true);
         $client_sign = hash_hmac('sha1', $session['auth_message'], $stored_key, true);
         $client_proof = $client_key ^ $client_sign;
         $payload .= ',p=' . base64_encode($client_proof);
         $query = ['saslContinue' => 1, 'conversationId' => $session['conversation_id'], 'payload' => base64_encode($payload)];
     } elseif ($session['step'] == 3) {
         $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
         if (!empty($in_payload['v'])) {
             $session['server_signature'] = $in_payload['v'];
             $query = ['saslContinue' => 1, 'conversationId' => $session['conversation_id'], 'payload' => base64_encode('')];
         }
     } elseif ($session['step'] == 4) {
         $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
         $res = $input['done'] ? ['ok' => 1, 'server_signature' => $session['server_signature']] : ['ok' => 0, 'errmsg' => 'Authentication failed.'];
         $session['cb']($res);
         return;
     }
     $this->saslScrumSHA1Conversation($session['dbname'], $query, function ($res) use($session) {
         $this->saslScrumSHA1Step($session, $res);
     }, $session['conn']);
 }
Example #22
0
 /**
  * Get state of workers.
  * @return array - information.
  */
 public static function getStateOfWorkers()
 {
     $offset = 0;
     $stat = ['idle' => 0, 'busy' => 0, 'alive' => 0, 'shutdown' => 0, 'preinit' => 0, 'init' => 0, 'reloading' => 0];
     $readed = 0;
     while (($buf = Daemon::$shm_wstate->read($readed, 1024)) !== false) {
         $buflen = mb_orig_strlen($buf);
         $readed += $buflen;
         for ($i = 0; $i < $buflen; ++$i) {
             $code = ord($buf[$i]);
             if ($code >= 100) {
                 // reloaded (shutdown)
                 $code -= 100;
                 if ($code !== Daemon::WSTATE_SHUTDOWN) {
                     ++$stat['alive'];
                     if (Daemon::$process instanceof Thread\Master) {
                         Daemon::$process->reloadWorker($offset + $i + 1);
                         ++$stat['reloading'];
                         continue;
                     }
                 }
             }
             if ($code === Daemon::WSTATE_IDLE) {
                 // idle
                 ++$stat['alive'];
                 ++$stat['idle'];
             } elseif ($code === Daemon::WSTATE_BUSY) {
                 // busy
                 ++$stat['alive'];
                 ++$stat['busy'];
             } elseif ($code === Daemon::WSTATE_SHUTDOWN) {
                 // shutdown
                 ++$stat['shutdown'];
             } elseif ($code === Daemon::WSTATE_PREINIT) {
                 // pre-init
                 ++$stat['alive'];
                 ++$stat['preinit'];
                 ++$stat['idle'];
             } elseif ($code === Daemon::WSTATE_INIT) {
                 // init
                 ++$stat['alive'];
                 ++$stat['init'];
                 ++$stat['idle'];
             }
         }
     }
     return $stat;
 }
Example #23
0
 protected function _writeResult(&$result, $bForceWrite = false)
 {
     $this->_buffer .= $result;
     if (static::$_bMBStringOrig) {
         $this->_bufferLoaded += mb_orig_strlen($result);
     } else {
         $this->_bufferLoaded += strlen($result);
     }
     if (true === $bForceWrite || $this->_bufferLoaded >= $this->_bufferSize || $this->_bComplete) {
         if (!$this->_dwnFileHandler) {
             $this->_dwnFileHandler = fopen(OBX_DOC_ROOT . $this->_dwnFolder . '/' . $this->_dwnFileBaseName . '.' . $this->_dwnFileExt, $this->_dwnFileOpenMode);
             if (!$this->_dwnFileHandler) {
                 $this->throwErrorException(new DownloadError('', DownloadError::E_CANT_OPEN_DWN_FILE));
             }
         }
         $bytesWritten = fwrite($this->_dwnFileHandler, $this->_buffer);
         if (false === $bytesWritten || $this->_bufferLoaded !== $bytesWritten) {
             $this->throwErrorException(new DownloadError('', DownloadError::E_CANT_WRT_2_DWN_FILE));
         }
         $this->_fileLoaded += $this->_bufferLoaded;
         $this->_buffer = null;
         $this->_bufferLoaded = 0;
     }
 }
Example #24
0
 /**
  * Generates closure-callback for readAllChunked
  * @param  callable $cb
  * @param  callable $chunkcb
  * @param  integer $size
  * @param  integer $offset
  * @param  integer $pri
  * @return callable
  */
 protected function readAllChunkedGenHandler($cb, $chunkcb, $size, &$offset, $pri)
 {
     return function ($file, $data) use($cb, $chunkcb, $size, &$offset, $pri) {
         $chunkcb($file, $data);
         $offset += mb_orig_strlen($data);
         $len = min($file->chunkSize, $size - $offset);
         if ($offset >= $size) {
             $cb($file, true);
             return;
         }
         eio_read($file->fd, $len, $offset, $pri, $this->readAllChunkedGenHandler($cb, $chunkcb, $size, $offset, $pri), $file);
     };
 }
Example #25
0
 /**
  * Output some data
  * @param  string $s String to out
  * @param  boolean $flush ob_flush?
  * @return boolean        Success
  */
 public function out($s, $flush = true)
 {
     if ($flush) {
         if (!Daemon::$obInStack) {
             // preventing recursion
             ob_flush();
         }
     }
     if ($this->aborted) {
         return false;
     }
     if (!isset($this->upstream)) {
         return false;
     }
     $l = mb_orig_strlen($s);
     $this->responseLength += $l;
     $this->ensureSentHeaders();
     if ($this->attrs->chunked) {
         for ($o = 0; $o < $l;) {
             $c = min($this->upstream->pool->config->chunksize->value, $l - $o);
             $chunk = dechex($c) . "\r\n" . ($c === $l ? $s : mb_orig_substr($s, $o, $c)) . "\r\n";
             if ($this->sendfp) {
                 $this->sendfp->write($chunk);
             } else {
                 $this->upstream->requestOut($this, $chunk);
             }
             $o += $c;
         }
         return true;
     } else {
         if ($this->sendfp) {
             $this->sendfp->write($s);
             return true;
         }
         if (Daemon::$compatMode) {
             echo $s;
             return true;
         }
         return $this->upstream->requestOut($this, $s);
     }
 }
Example #26
0
 /**
  * Creates Request.
  * @param  object $req Request.
  * @param  object $upstream Upstream application instance.
  * @return object           Request.
  */
 public function beginRequest($req, $upstream)
 {
     $e = array_map('rawurldecode', explode('/', $req->attrs->server['DOCUMENT_URI']));
     $serverId = null;
     $sessId = null;
     /* Route discovery */
     $path = null;
     $extra = [];
     do {
         foreach ($this->wss as $wss) {
             $try = implode('/', $e);
             if ($try === '') {
                 $try = '/';
             }
             if ($wss->routeExists($try)) {
                 $path = $try;
                 break 2;
             }
         }
         array_unshift($extra, array_pop($e));
     } while (sizeof($e) > 0);
     if ($path === null) {
         return $this->callMethod('NotFound', $req, $upstream);
     }
     if (sizeof($extra) > 0 && end($extra) === '') {
         array_pop($extra);
     }
     $method = sizeof($extra) ? array_pop($extra) : null;
     if ($method === null) {
         $method = 'Welcome';
     } elseif ($method === 'info') {
     } elseif (preg_match('~^iframe(?:-([^/]*))?\\.html$~', $method, $m)) {
         $method = 'Iframe';
         $version = isset($m[1]) ? $m[1] : null;
     } else {
         if (sizeof($extra) < 2) {
             return $this->callMethod('NotFound', $req, $upstream);
         }
         $sessId = array_pop($extra);
         $serverId = array_pop($extra);
         if ($sessId === '' || $serverId === '' || mb_orig_strpos($sessId, '.') !== false || mb_orig_strpos($serverId, '.') !== false) {
             return $this->callMethod('NotFound', $req, $upstream);
         }
     }
     $req->attrs->sessId = $sessId;
     $req->attrs->serverId = $serverId;
     $req->attrs->path = $path;
     $req = $this->callMethod($method, $req, $upstream);
     if ($req instanceof Methods\Iframe && mb_orig_strlen($version)) {
         $req->attrs->version = $version;
     }
     return $req;
 }
Example #27
0
	public static function strlen($s)
	{
		if (function_exists('mb_orig_strlen'))
			return mb_orig_strlen($s);
		return strlen($s);
	}
Example #28
0
 /**
  * Called when new data received
  * @return void
  */
 public function onRead()
 {
     Timer::setTimeout($this->keepaliveTimer);
     while (($line = $this->readline()) !== null) {
         if ($line === '') {
             continue;
         }
         if (mb_orig_strlen($line) > 512) {
             Daemon::$process->log('IRCBouncerConnection error: buffer overflow.');
             $this->finish();
             return;
         }
         $line = mb_orig_substr($line, 0, -mb_orig_strlen($this->EOL));
         $p = mb_orig_strpos($line, ':', 1);
         $max = $p ? substr_count($line, " ", 0, $p) + 1 : 18;
         $e = explode(" ", $line, $max);
         $i = 0;
         $cmd = $e[$i++];
         $args = [];
         for ($s = min(sizeof($e), 14); $i < $s; ++$i) {
             if ($e[$i][0] === ':') {
                 $args[] = mb_orig_substr($e[$i], 1);
                 break;
             }
             $args[] = $e[$i];
         }
         if (ctype_digit($cmd)) {
             $code = (int) $cmd;
             $cmd = isset(IRC::$codes[$code]) ? IRC::$codes[$code] : 'UNKNOWN-' . $code;
         }
         $this->onCommand($cmd, $args);
     }
     if (mb_orig_strlen($this->buf) > 512) {
         Daemon::$process->log('IRCClientConnection error: buffer overflow.');
         $this->finish();
     }
 }
Example #29
0
 /**
  * Wrapper for mbstring-overloaded strlen().
  *
  * @param string $body
  * @return int
  */
 private function _strlen($body)
 {
     return function_exists('mb_orig_strlen') ? mb_orig_strlen($body) : strlen($body);
 }
Example #30
0
 /**
  * Constructor
  * @return void
  */
 protected function __construct($file, $target, $included = false)
 {
     $this->file = $file;
     $this->target = $target;
     $this->revision = ++Object::$lastRevision;
     $this->data = file_get_contents($file);
     if (substr($this->data, 0, 2) === '#!') {
         if (!is_executable($file)) {
             $this->raiseError('Shebang (#!) detected in the first line, but file hasn\'t +x mode.');
             return;
         }
         $this->data = shell_exec($file);
     }
     $this->data = str_replace("\r", '', $this->data);
     $this->length = mb_orig_strlen($this->data);
     $this->state[] = [static::T_ALL, $this->target];
     $this->tokens = [static::T_COMMENT => function ($c) {
         if ($c === "\n") {
             array_pop($this->state);
         }
     }, static::T_STRING_DOUBLE => function ($q) {
         $str = '';
         ++$this->p;
         for (; $this->p < $this->length; ++$this->p) {
             $c = $this->getCurrentChar();
             if ($c === $q) {
                 ++$this->p;
                 break;
             } elseif ($c === '\\') {
                 next:
                 $n = $this->getNextChar();
                 if ($n === $q) {
                     $str .= $q;
                     ++$this->p;
                 } elseif (ctype_digit($n)) {
                     $def = $n;
                     ++$this->p;
                     for (; $this->p < min($this->length, $this->p + 2); ++$this->p) {
                         $n = $this->getNextChar();
                         if (!ctype_digit($n)) {
                             break;
                         }
                         $def .= $n;
                     }
                     $str .= chr((int) $def);
                 } elseif ($n === 'x' || $n === 'X') {
                     $def = $n;
                     ++$this->p;
                     for (; $this->p < min($this->length, $this->p + 2); ++$this->p) {
                         $n = $this->getNextChar();
                         if (!ctype_xdigit($n)) {
                             break;
                         }
                         $def .= $n;
                     }
                     $str .= chr((int) hexdec($def));
                 } else {
                     $str .= $c;
                 }
             } else {
                 $str .= $c;
             }
         }
         if ($this->p >= $this->length) {
             $this->raiseError('Unexpected End-Of-File.');
         }
         return $str;
     }, static::T_STRING => function ($q) {
         $str = '';
         ++$this->p;
         for (; $this->p < $this->length; ++$this->p) {
             $c = $this->getCurrentChar();
             if ($c === $q) {
                 ++$this->p;
                 break;
             } elseif ($c === '\\') {
                 if ($this->getNextChar() === $q) {
                     $str .= $q;
                     ++$this->p;
                 } else {
                     $str .= $c;
                 }
             } else {
                 $str .= $c;
             }
         }
         if ($this->p >= $this->length) {
             $this->raiseError('Unexpected End-Of-File.');
         }
         return $str;
     }, static::T_ALL => function ($c) {
         if (ctype_space($c)) {
         } elseif ($c === '#') {
             $this->state[] = [static::T_COMMENT];
         } elseif ($c === '}') {
             if (sizeof($this->state) > 1) {
                 $this->purgeScope($this->getCurrentScope());
                 array_pop($this->state);
             } else {
                 $this->raiseError('Unexpected \'}\'');
             }
         } elseif (ctype_alnum($c) || $c === '\\') {
             $elements = [''];
             $elTypes = [null];
             $i = 0;
             $tokenType = 0;
             $newLineDetected = null;
             for (; $this->p < $this->length; ++$this->p) {
                 $prePoint = [$this->line, $this->col - 1];
                 $c = $this->getCurrentChar();
                 if (ctype_space($c) || $c === '=' || $c === ',') {
                     if ($c === "\n") {
                         $newLineDetected = $prePoint;
                     }
                     if ($elTypes[$i] !== null) {
                         ++$i;
                         $elTypes[$i] = null;
                     }
                 } elseif ($c === '\'') {
                     if ($elTypes[$i] !== null) {
                         $this->raiseError('Unexpected T_STRING.');
                     }
                     $string = $this->token(static::T_STRING, $c);
                     --$this->p;
                     if ($elTypes[$i] === null) {
                         $elements[$i] = $string;
                         $elTypes[$i] = static::T_STRING;
                     }
                 } elseif ($c === '"') {
                     if ($elTypes[$i] !== null) {
                         $this->raiseError('Unexpected T_STRING_DOUBLE.');
                     }
                     $string = $this->token(static::T_STRING_DOUBLE, $c);
                     --$this->p;
                     if ($elTypes[$i] === null) {
                         $elements[$i] = $string;
                         $elTypes[$i] = static::T_STRING_DOUBLE;
                     }
                 } elseif ($c === '}') {
                     $this->raiseError('Unexpected \'}\' instead of \';\' or \'{\'');
                 } elseif ($c === ';') {
                     if ($newLineDetected) {
                         $this->raiseError('Unexpected new-line instead of \';\'', 'notice', $newLineDetected[0], $newLineDetected[1]);
                     }
                     $tokenType = static::T_VAR;
                     break;
                 } elseif ($c === '{') {
                     $tokenType = static::T_BLOCK;
                     break;
                 } else {
                     if ($elTypes[$i] === static::T_STRING) {
                         $this->raiseError('Unexpected T_CVALUE.');
                     } else {
                         if (!isset($elements[$i])) {
                             $elements[$i] = '';
                         }
                         $elements[$i] .= $c;
                         $elTypes[$i] = static::T_CVALUE;
                     }
                 }
             }
             foreach ($elTypes as $k => $v) {
                 if (static::T_CVALUE === $v) {
                     if (ctype_digit($elements[$k])) {
                         $elements[$k] = (int) $elements[$k];
                     } elseif (is_numeric($elements[$k])) {
                         $elements[$k] = (double) $elements[$k];
                     } else {
                         $l = strtolower($elements[$k]);
                         if ($l === 'true' || $l === 'on') {
                             $elements[$k] = true;
                         } elseif ($l === 'false' || $l === 'off') {
                             $elements[$k] = false;
                         } elseif ($l === 'null') {
                             $elements[$k] = null;
                         }
                     }
                 }
             }
             if ($tokenType === 0) {
                 $this->raiseError('Expected \';\' or \'{\'');
             } elseif ($tokenType === static::T_VAR) {
                 $name = str_replace('-', '', strtolower($elements[0]));
                 if (sizeof($elements) > 2) {
                     $value = array_slice($elements, 1);
                 } else {
                     $value = isset($elements[1]) ? $elements[1] : null;
                 }
                 $scope = $this->getCurrentScope();
                 if ($name === 'include') {
                     if (!is_array($value)) {
                         $value = [$value];
                     }
                     foreach ($value as $path) {
                         if (substr($path, 0, 1) !== '/') {
                             $path = 'conf/' . $path;
                         }
                         $files = glob($path);
                         if ($files) {
                             foreach ($files as $fn) {
                                 try {
                                     static::parse($fn, $scope, true);
                                 } catch (InfiniteRecursion $e) {
                                     $this->raiseError('Cannot include \'' . $fn . '\' as a part of itself, it may cause an infinite recursion.');
                                 }
                             }
                         }
                     }
                 } else {
                     if (sizeof($elements) === 1) {
                         $value = true;
                         $elements[1] = true;
                         $elTypes[1] = static::T_CVALUE;
                     } elseif ($value === null) {
                         $value = null;
                         $elements[1] = null;
                         $elTypes[1] = static::T_CVALUE;
                     }
                     if (isset($scope->{$name})) {
                         if ($scope->{$name}->source !== 'cmdline') {
                             if ($elTypes[1] === static::T_CVALUE && is_string($value)) {
                                 $scope->{$name}->pushHumanValue($value);
                             } else {
                                 $scope->{$name}->pushValue($value);
                             }
                             $scope->{$name}->source = 'config';
                             $scope->{$name}->revision = $this->revision;
                         }
                     } elseif ($scope instanceof Section) {
                         $scope->{$name} = new Generic();
                         $scope->{$name}->source = 'config';
                         $scope->{$name}->revision = $this->revision;
                         $scope->{$name}->pushValue($value);
                         $scope->{$name}->setValueType($value);
                     } else {
                         $this->raiseError('Unrecognized parameter \'' . $name . '\'');
                     }
                 }
             } elseif ($tokenType === static::T_BLOCK) {
                 $scope = $this->getCurrentScope();
                 $sectionName = implode('-', $elements);
                 $sectionName = strtr($sectionName, '-. ', ':::');
                 if (!isset($scope->{$sectionName})) {
                     $scope->{$sectionName} = new Section();
                 }
                 $scope->{$sectionName}->source = 'config';
                 $scope->{$sectionName}->revision = $this->revision;
                 $this->state[] = [static::T_ALL, $scope->{$sectionName}];
             }
         } else {
             $this->raiseError('Unexpected char \'' . Debug::exportBytes($c) . '\'');
         }
     }];
     for (; $this->p < $this->length; ++$this->p) {
         $c = $this->getCurrentChar();
         $e = end($this->state);
         $this->token($e[0], $c);
     }
     if (!$included) {
         $this->purgeScope($this->target);
     }
     if (Daemon::$config->verbosetty->value) {
         Daemon::log('Loaded config file: ' . escapeshellarg($file));
     }
 }