public function Prepend()
 {
     if (!empty($_POST['data'])) {
         /* POST contains:
         		         data (mandatory) = json encoded SJCL encrypted text (containing keys: iv,salt,ct)
         
         		         All optional data will go to meta information:
         		         expire (optional) = expiration delay (never,5min,10min,1hour,1day,1week,1month,1year,burn) (default:never)
         		         opendiscusssion (optional) = is the discussion allowed on this paste ? (0/1) (default:0)
         		         syntaxcoloring (optional) = should this paste use syntax coloring when displaying.
         		         nickname (optional) = son encoded SJCL encrypted text nickname of author of comment (containing keys: iv,salt,ct)
         		         parentid (optional) = in discussion, which comment this comment replies to.
         		         pasteid (optional) = in discussion, which paste this comment belongs to.
         		    */
         header('Content-type: application/json');
         $error = false;
         // Create storage directory if it does not exist.
         if (!is_dir(PLX_ROOT . 'data/zb')) {
             mkdir(PLX_ROOT . 'data/zb', 0705);
             file_put_contents(PLX_ROOT . 'data/zb/.htaccess', "Allow from none\nDeny from all\n", LOCK_EX);
         }
         // Make sure last paste from the IP address was more than 10 seconds ago.
         if (!cmp_trafic_limiter_canPass($_SERVER['REMOTE_ADDR'])) {
             echo json_encode(array('status' => 1, 'message' => 'Please wait 10 seconds between each post.'));
             exit;
         }
         // Make sure content is not too big.
         $data = $_POST['data'];
         if (strlen($data) > 2000000) {
             echo json_encode(array('status' => 1, 'message' => 'Paste is limited to 2 Mb of encrypted data.'));
             exit;
         }
         // Make sure format is correct.
         if (!cmp_validSJCL($data)) {
             echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
             exit;
         }
         // Read additional meta-information.
         $meta = array();
         // Read expiration date
         if (!empty($_POST['expire'])) {
             $expire = $_POST['expire'];
             if ($expire == '5min') {
                 $meta['expire_date'] = time() + 5 * 60;
             } elseif ($expire == '10min') {
                 $meta['expire_date'] = time() + 10 * 60;
             } elseif ($expire == '1hour') {
                 $meta['expire_date'] = time() + 60 * 60;
             } elseif ($expire == '1day') {
                 $meta['expire_date'] = time() + 24 * 60 * 60;
             } elseif ($expire == '1week') {
                 $meta['expire_date'] = time() + 7 * 24 * 60 * 60;
             } elseif ($expire == '1month') {
                 $meta['expire_date'] = time() + 30 * 24 * 60 * 60;
             } elseif ($expire == '1year') {
                 $meta['expire_date'] = time() + 365 * 24 * 60 * 60;
             }
         }
         // Destroy the paste when it is read.
         if (!empty($_POST['burnafterreading'])) {
             $burnafterreading = $_POST['burnafterreading'];
             if ($burnafterreading != '0' && $burnafterreading != '1') {
                 $error = true;
             }
             if ($burnafterreading != '0') {
                 $meta['burnafterreading'] = true;
             }
         }
         // Read open discussion flag
         if (!empty($_POST['opendiscussion'])) {
             $opendiscussion = $_POST['opendiscussion'];
             if ($opendiscussion != '0' && $opendiscussion != '1') {
                 $error = true;
             }
             if ($opendiscussion != '0') {
                 $meta['opendiscussion'] = true;
             }
         }
         // Should we use syntax coloring when displaying ?
         if (!empty($_POST['syntaxcoloring'])) {
             $syntaxcoloring = $_POST['syntaxcoloring'];
             if ($syntaxcoloring != '0' && $syntaxcoloring != '1') {
                 $error = true;
             }
             if ($syntaxcoloring != '0') {
                 $meta['syntaxcoloring'] = true;
             }
         }
         // You can't have an open discussion on a "Burn after reading" paste:
         if (isset($meta['burnafterreading'])) {
             unset($meta['opendiscussion']);
         }
         // Optional nickname for comments
         if (!empty($_POST['nickname'])) {
             $nick = $_POST['nickname'];
             if (!cmp_validSJCL($nick)) {
                 $error = true;
             } else {
                 $meta['nickname'] = $nick;
                 // Generation of the anonymous avatar (Vizhash):
                 // If a nickname is provided, we generate a Vizhash.
                 // (We assume that if the user did not enter a nickname, he/she wants
                 // to be anonymous and we will not generate the vizhash.)
                 $vz = new cmp_vizhash16x16();
                 $pngdata = $vz->generate($_SERVER['REMOTE_ADDR']);
                 if ($pngdata != '') {
                     $meta['vizhash'] = 'data:image/png;base64,' . base64_encode($pngdata);
                 }
                 // Once the avatar is generated, we do not keep the IP address, nor its hash.
             }
         }
         if ($error) {
             echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
             exit;
         }
         // Add post date to meta.
         $meta['postdate'] = time();
         // We just want a small hash to avoid collisions: Half-MD5 (64 bits) will do the trick.
         $dataid = substr(hash('md5', $data), 0, 16);
         $is_comment = !empty($_POST['parentid']) && !empty($_POST['pasteid']);
         // Is this post a comment ?
         $storage = array('data' => $data);
         if (count($meta) > 0) {
             $storage['meta'] = $meta;
         }
         // Add meta-information only if necessary.
         if ($is_comment) {
             $pasteid = $_POST['pasteid'];
             $parentid = $_POST['parentid'];
             if (!preg_match('/\\A[a-f\\d]{16}\\z/', $pasteid)) {
                 echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
                 exit;
             }
             if (!preg_match('/\\A[a-f\\d]{16}\\z/', $parentid)) {
                 echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
                 exit;
             }
             unset($storage['expire_date']);
             // Comment do not expire (it's the paste that expires)
             unset($storage['opendiscussion']);
             unset($storage['syntaxcoloring']);
             // Make sure paste exists.
             $storagedir = cmp_dataid2path($pasteid);
             if (!is_file($storagedir . $pasteid)) {
                 echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
                 exit;
             }
             // Make sure the discussion is opened in this paste.
             $paste = json_decode(file_get_contents($storagedir . $pasteid));
             if (!$paste->meta->opendiscussion) {
                 echo json_encode(array('status' => 1, 'message' => 'Invalid data.'));
                 exit;
             }
             $discdir = cmp_dataid2discussionpath($pasteid);
             $filename = $pasteid . '.' . $dataid . '.' . $parentid;
             if (!is_dir($discdir)) {
                 mkdir($discdir, $mode = 0705, $recursive = true);
             }
             if (is_file($discdir . $filename)) {
                 echo json_encode(array('status' => 1, 'message' => 'You are unlucky. Try again.'));
                 exit;
             }
             file_put_contents($discdir . $filename, json_encode($storage), LOCK_EX);
             echo json_encode(array('status' => 0, 'id' => $dataid));
             // 0 = no error
             exit;
         } else {
             $storagedir = cmp_dataid2path($dataid);
             if (!is_dir($storagedir)) {
                 mkdir($storagedir, $mode = 0705, $recursive = true);
             }
             if (is_file($storagedir . $dataid)) {
                 echo json_encode(array('status' => 1, 'message' => 'You are unlucky. Try again.'));
                 exit;
             }
             // New paste
             file_put_contents($storagedir . $dataid, json_encode($storage), LOCK_EX);
             // Generate the "delete" token.
             // The token is the hmac of the pasteid signed with the server salt.
             // The paste can be delete by calling http://myserver.com/zerobin/?pasteid=<pasteid>&deletetoken=<deletetoken>
             $deletetoken = hash_hmac('sha1', $dataid, cmp_getServerSalt());
             echo json_encode(array('status' => 0, 'id' => $dataid, 'deletetoken' => $deletetoken));
             // 0 = no error
             exit;
         }
         echo json_encode(array('status' => 1, 'message' => 'Server error.'));
         exit;
     }
 }
Пример #2
0
function cmp_processPasteFetch($pasteid)
{
    $pasteid = str_replace(array('zb=', 'zb/'), '', $pasteid);
    if (preg_match('/\\A[a-f\\d]{16}\\z/', $pasteid)) {
        $filename = cmp_dataid2path($pasteid) . $pasteid;
        if (!is_file($filename)) {
            return array('', 'Paste does not exist, has expired or has been deleted.', '');
        }
    } else {
        return array('', 'Invalid data', '');
    }
    // Get the paste itself.
    $paste = json_decode(file_get_contents($filename));
    // See if paste has expired.
    if (isset($paste->meta->expire_date) && $paste->meta->expire_date < time()) {
        cmp_deletePaste($pasteid);
        // Delete the paste
        return array('', 'Paste does not exist, has expired or has been deleted.', '');
    }
    // We kindly provide the remaining time before expiration (in seconds)
    if (property_exists($paste->meta, 'expire_date')) {
        $paste->meta->remaining_time = $paste->meta->expire_date - time();
    }
    $messages = array($paste);
    // The paste itself is the first in the list of encrypted messages.
    // If it's a discussion, get all comments.
    if (property_exists($paste->meta, 'opendiscussion') && $paste->meta->opendiscussion) {
        $comments = array();
        $datadir = cmp_dataid2discussionpath($pasteid);
        if (!is_dir($datadir)) {
            mkdir($datadir, $mode = 0705, $recursive = true);
        }
        $dhandle = opendir($datadir);
        while (false !== ($filename = readdir($dhandle))) {
            if (is_file($datadir . $filename)) {
                $comment = json_decode(file_get_contents($datadir . $filename));
                // Filename is in the form pasteid.commentid.parentid:
                // - pasteid is the paste this reply belongs to.
                // - commentid is the comment identifier itself.
                // - parentid is the comment this comment replies to (It can be pasteid)
                $items = explode('.', $filename);
                $comment->meta->commentid = $items[1];
                // Add some meta information not contained in file.
                $comment->meta->parentid = $items[2];
                $comments[$comment->meta->postdate] = $comment;
                // Store in table
            }
        }
        closedir($dhandle);
        ksort($comments);
        // Sort comments by date, oldest first.
        $messages = array_merge($messages, $comments);
    }
    $CIPHERDATA = json_encode($messages);
    # si affichage des articles coté visiteurs:
    if (!defined('PLX_ADMIN')) {
        // If the paste was meant to be read only once, delete it.
        if (property_exists($paste->meta, 'burnafterreading') && $paste->meta->burnafterreading) {
            cmp_deletePaste($pasteid);
        }
    }
    return array($CIPHERDATA, '', '');
}