\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82 www.csarite.com
KUJUNTI.ID MINISH3LL
Path : /opt/z-push/backend/zimbra/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : //opt/z-push/backend/zimbra/zimbraHttpStreamWrapper.php


<?php
/***********************************************
* File          :   ZimbraHttpStreamWrapper.php
* Revision      :   3 (18-Dec-2016)
* Project       :   Z-Push Zimbra Backend
*                   http://sourceforge.net/projects/zimbrabackend
* Description   :   Stream Wrapper class to wrap a standard php http stream and to provide the length of the file for download from zimbra
*
* Copyright     :   Vincent Sherwood
************************************************

The zimbra nginx server does not provide a Content-Length header for a standard http stream call. This class is designed to wrap the standard HTTP
stream as well as to provide the length of the data to be downloaded which is required for the processMultipart function in Z-Push's wbxmlencoder class.

Changed for Revision 3
 - Added options for verifying the SSL Peer and HostName

Changed for Revision 2
 - Fixed type on stream_stat debug message

************************************************/

class ZimbraHttpStreamWrapper {
    const PROTOCOL = "zimbrahttpstream";

    private $zimbrahttpstream;
    private $position;
    private $zimbrahttpstreamlength;

    /**
     * Opens the stream
     * The mapistream reference is passed over the context
     *
     * @param string    $path           Specifies the URL that was passed to the original function
     * @param string    $mode           The mode used to open the file, as detailed for fopen()
     * @param int       $options        Holds additional flags set by the streams API
     * @param string    $opened_path    If the path is opened successfully, and STREAM_USE_PATH is set in options,
     *                                  opened_path should be set to the full path of the file/resource that was actually opened.
     *
     * @access public
     * @return boolean
     */
    public function stream_open($path, $mode, $options, &$opened_path) {
		
    try {

        $contextOptions = stream_context_get_options($this->context);

        if (!isset($contextOptions[self::PROTOCOL]['publicUrl']) || !isset($contextOptions[self::PROTOCOL]['authToken']) || !isset($contextOptions[self::PROTOCOL]['id']) || !isset($contextOptions[self::PROTOCOL]['part']) || !isset($contextOptions[self::PROTOCOL]['length']))
            return false;

		$publicUrl = $contextOptions[self::PROTOCOL]['publicUrl'];
		$authToken = $contextOptions[self::PROTOCOL]['authToken'];
        $id = $contextOptions[self::PROTOCOL]['id'];
        $part = $contextOptions[self::PROTOCOL]['part'];
        $sslVerifyPeer = $contextOptions[self::PROTOCOL]['sslVerifyPeer'];
        $sslVerifyPeerName = $contextOptions[self::PROTOCOL]['sslVerifyPeerName'];

        $this->position = 0;

		// STREAM OPENING LOGIC STARTS HERE
        if (!$id) { return null; }
        $url = $publicUrl . "/service/content/get?id=" . $id;
        if ($part != "") {
            $url = $url . "&part=" . $part;
        }

        $opts = array(
            'http' => array(
                'method' => 'GET',
                'header' => 'Content-type: application/x-www-form-urlencoded' . "\r\n" . 'Cookie: ' .  'ZM_AUTH_TOKEN=' . $authToken . "\r\n" ,
            ),
            'ssl' => array(
                'verify_peer' => $sslVerifyPeer,
                'verify_peer_name' => (!(0 == $sslVerifyPeerName))
            ),
        );
        $context = stream_context_create($opts);
        $this->zimbrahttpstream = fopen($url, 'rb', false, $context);

		$this->zimbrahttpstreamlength = $contextOptions[self::PROTOCOL]['length'];

		// STREAM OPENING LOGIC ENDS HERE
		// position should be zero, $this->zimbrahttpstream should be the http stream at the beginning of the data,  $this->zimbrahttpstreamlength should contain the correct length
			
        ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_open(): initialized stream length: %d", $this->zimbrahttpstreamlength));

        return true;

    } catch (\Exception $e) {

        if ($options & STREAM_REPORT_ERRORS) {
            trigger_error($e->getMessage(), E_USER_WARNING);
        }

        return false;
    }

    }

    /**
     * Reads from stream
     *
     * @param int $len      amount of bytes to be read
     *
     * @access public
     * @return string
     */
    public function stream_read($len) {
//        ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_read(): Reading bytes from stream length: %d", $len));
        $data = fread($this->zimbrahttpstream, $len);
        $this->position += strlen($data);
        return $data;
    }

    /**
     * Writes data to the stream.
     *
     * @param string $data
     * @return int
     */
    public function stream_write($data){
		// writing to the wrapper should not be possible
		return 0;
    }

    /**
     * Stream "seek" functionality.
     *
     * @param int $offset
     * @param int $whence
     * @return boolean
     */
    public function stream_seek($offset, $whence = SEEK_SET) {
//        ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_seek(): Looking for Offset: %d", $offset));
		// TODO if you implement SEEK it's not enough just to set the internal pointer, but the underlying stream also needs to be seeked to the correct position. 

        if ($whence == SEEK_CUR) {
            $this->position += $offset;
        }
        else if ($whence == SEEK_END) {
            $this->position = $this->zimbrahttpstreamlength + $offset;
        }
        else {
            $this->position = $offset;
        }
		
		// this is probably not possible with a http stream, if, it's enough to do:
		return fseek($this->zimbrahttpstream, $offset, $whence);
    }

    /**
     * Returns the current position on stream
     *
     * @access public
     * @return int
     */
    public function stream_tell() {
 //       ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_tell(): At position: %d", $this->position));
        return $this->position;
    }

   /**
     * Indicates if 'end of file' is reached
     *
     * @access public
     * @return boolean
     */
    public function stream_eof() {
//        ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_eof(): Position: %d - EOF: %d", $this->position, $this->zimbrahttpstreamlength));
        return ($this->position >= $this->zimbrahttpstreamlength);
    }

    /**
    * Retrieves information about a stream
    *
    * @access public
    * @return array
    */
    public function stream_stat() {
        ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZimbraHttpStreamWrapper->stream_stat(): Stat: %d", $this->zimbrahttpstreamlength));
        return array(
            7               => $this->zimbrahttpstreamlength,
            'size'          => $this->zimbrahttpstreamlength,
        );
    }

   /**
     * Instantiates a ZimbraHttpStreamWrapper
     *
     * @param string    $url               The url of the entry that should be streamed.
	 * @param string    $authtoken         The authtoken required to access the url.
	 * @param string    $id      	       The id .. 
	 * @param string    $part      	       The part ..
	 * @param long      $length   	       The length of the data ..
	 * @param int       $sslVerifyPeer     Flag to indicate if zimbra certificate should be validated 
	 * @param string    $sslVerifyPeerName Flag to indicate if the hostname in the zimbra certificate should be validated 
     *
     * @access public
     * @return ZimbraHttpStreamWrapper
     */
     static public function Open($authToken, $publicUrl, $id, $part, $length, $sslVerifyPeer = 0, $sslVerifyPeerName = 0) {

        $opts = array(
                self::PROTOCOL => array(
					'publicUrl' => $publicUrl,
					'authToken' => $authToken,
					'id' => $id,
					'part' => $part,
					'length' => $length,
					'sslVerifyPeer' => $sslVerifyPeer,
					'sslVerifyPeerName' => $sslVerifyPeerName,
				)
        );

        $context = stream_context_create($opts);
        return fopen(self::PROTOCOL . "://",'rb', false, $context);
    }
}

stream_wrapper_register(ZimbraHttpStreamWrapper::PROTOCOL, "ZimbraHttpStreamWrapper");


© KUJUNTI.ID