Пример #1
0
 public function testVizhashGeneratesUniquePngsPerIp()
 {
     $vz = new vizhash16x16();
     $pngdata = $vz->generate('127.0.0.1');
     file_put_contents($this->_file, $pngdata);
     $finfo = new finfo(FILEINFO_MIME_TYPE);
     $this->assertEquals('image/png', $finfo->file($this->_file));
     $this->assertNotEquals($pngdata, $vz->generate('2001:1620:2057:dead:beef::cafe:babe'));
     $this->assertEquals($pngdata, $vz->generate('127.0.0.1'));
 }
Пример #2
0
 public function testVizhashGeneratesUniquePngsPerIp()
 {
     $vz = new vizhash16x16();
     $pngdata = $vz->generate('127.0.0.1');
     file_put_contents($this->_file, $pngdata);
     $finfo = new finfo(FILEINFO_MIME_TYPE);
     $this->assertEquals('image/png', $finfo->file($this->_file));
     $this->assertNotEquals($pngdata, $vz->generate('2001:1620:2057:dead:beef::cafe:babe'));
     $this->assertEquals($pngdata, $vz->generate('127.0.0.1'));
     // generating new salt
     $salt = serversalt::get();
     require 'mcrypt_mock.php';
     $this->assertNotEquals($salt, serversalt::generate());
 }
Пример #3
0
 // 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 (!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 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);
Пример #4
0
 /**
  * Store new paste or comment
  *
  * 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)
  * nickname (optional) = in discussion, 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.
  *
  * @access private
  * @param  string $data
  * @return void
  */
 private function _create($data)
 {
     header('Content-type: application/json');
     $error = false;
     // Make sure last paste from the IP address was more than X seconds ago.
     trafficlimiter::setLimit($this->_conf['traffic']['limit']);
     trafficlimiter::setPath($this->_conf['traffic']['dir']);
     if (!trafficlimiter::canPass($_SERVER['REMOTE_ADDR'])) {
         $this->_return_message(1, 'Please wait ' . $this->_conf['traffic']['limit'] . ' seconds between each post.');
     }
     // Make sure content is not too big.
     $sizelimit = (int) $this->_getMainConfig('sizelimit', 2097152);
     if (strlen($data) > $sizelimit) {
         $this->_return_message(1, 'Paste is limited to ' . filter::size_humanreadable($sizelimit) . ' of encrypted data.');
     }
     // Make sure format is correct.
     if (!sjcl::isValid($data)) {
         $this->_return_message(1, 'Invalid data.');
     }
     // Read additional meta-information.
     $meta = array();
     // Read expiration date
     if (!empty($_POST['expire'])) {
         $selected_expire = (string) $_POST['expire'];
         if (array_key_exists($selected_expire, $this->_conf['expire_options'])) {
             $expire = $this->_conf['expire_options'][$selected_expire];
         } else {
             $expire = $this->_conf['expire_options'][$this->_conf['expire']['default']];
         }
         if ($expire > 0) {
             $meta['expire_date'] = time() + $expire;
         }
     }
     // Destroy the paste when it is read.
     if (!empty($_POST['burnafterreading'])) {
         $burnafterreading = $_POST['burnafterreading'];
         if ($burnafterreading !== '0') {
             if ($burnafterreading !== '1') {
                 $error = true;
             }
             $meta['burnafterreading'] = true;
         }
     }
     // Read open discussion flag.
     if ($this->_conf['main']['opendiscussion'] && !empty($_POST['opendiscussion'])) {
         $opendiscussion = $_POST['opendiscussion'];
         if ($opendiscussion !== '0') {
             if ($opendiscussion !== '1') {
                 $error = true;
             }
             $meta['opendiscussion'] = 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'])) {
         // 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.)
         $nick = $_POST['nickname'];
         if (!sjcl::isValid($nick)) {
             $error = true;
         } else {
             $meta['nickname'] = $nick;
             $vz = new 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) {
         $this->_return_message(1, 'Invalid data.');
     }
     // 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);
     $storage = array('data' => $data);
     // Add meta-information only if necessary.
     if (count($meta)) {
         $storage['meta'] = $meta;
     }
     // The user posts a comment.
     if (!empty($_POST['parentid']) && !empty($_POST['pasteid'])) {
         $pasteid = (string) $_POST['pasteid'];
         $parentid = (string) $_POST['parentid'];
         if (!filter::is_valid_paste_id($pasteid) || !filter::is_valid_paste_id($parentid)) {
             $this->_return_message(1, 'Invalid data.');
         }
         // Comments do not expire (it's the paste that expires)
         unset($storage['expire_date']);
         unset($storage['opendiscussion']);
         // Make sure paste exists.
         if (!$this->_model()->exists($pasteid)) {
             $this->_return_message(1, 'Invalid data.');
         }
         // Make sure the discussion is opened in this paste.
         $paste = $this->_model()->read($pasteid);
         if (!$paste->meta->opendiscussion) {
             $this->_return_message(1, 'Invalid data.');
         }
         // Check for improbable collision.
         if ($this->_model()->existsComment($pasteid, $parentid, $dataid)) {
             $this->_return_message(1, 'You are unlucky. Try again.');
         }
         // New comment
         if ($this->_model()->createComment($pasteid, $parentid, $dataid, $storage) === false) {
             $this->_return_message(1, 'Error saving comment. Sorry.');
         }
         // 0 = no error
         $this->_return_message(0, $dataid);
     } else {
         // Check for improbable collision.
         if ($this->_model()->exists($dataid)) {
             $this->_return_message(1, 'You are unlucky. Try again.');
         }
         // New paste
         if ($this->_model()->create($dataid, $storage) === false) {
             $this->_return_message(1, 'Error saving paste. Sorry.');
         }
         // 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, serversalt::get());
         // 0 = no error
         $this->_return_message(0, $dataid, array('deletetoken' => $deletetoken));
     }
     $this->_return_message(1, 'Server error.');
 }
Пример #5
0
 public function testImplicitDefaults()
 {
     $pasteData = helper::getPaste();
     $commentData = helper::getComment();
     $this->_model->getPaste(helper::getPasteId())->delete();
     $paste = $this->_model->getPaste();
     $paste->setData($pasteData['data']);
     $paste->setBurnafterreading();
     $paste->setOpendiscussion();
     // not setting a formatter, should use default one
     $paste->store();
     $paste = $this->_model->getPaste(helper::getPasteId())->get();
     // ID was set based on data
     $this->assertEquals(true, property_exists($paste->meta, 'burnafterreading') && $paste->meta->burnafterreading, 'burn after reading takes precendence');
     $this->assertEquals(false, property_exists($paste->meta, 'opendiscussion') && $paste->meta->opendiscussion, 'opendiscussion is disabled');
     $this->assertEquals($this->_conf->getKey('defaultformatter'), $paste->meta->formatter, 'default formatter is set');
     $this->_model->getPaste(helper::getPasteId())->delete();
     $paste = $this->_model->getPaste();
     $paste->setData($pasteData['data']);
     $paste->setBurnafterreading('0');
     $paste->setOpendiscussion();
     $paste->store();
     $vz = new vizhash16x16();
     $pngdata = 'data:image/png;base64,' . base64_encode($vz->generate($_SERVER['REMOTE_ADDR']));
     $comment = $paste->getComment(helper::getPasteId());
     $comment->setData($commentData['data']);
     $comment->setNickname($commentData['meta']['nickname']);
     $comment->store();
     $comment = $paste->getComment(helper::getPasteId(), helper::getCommentId())->get();
     $this->assertEquals($pngdata, $comment->meta->vizhash, 'nickname triggers vizhash to be set');
 }
Пример #6
0
 /**
  * Set nickname.
  *
  * @access public
  * @param string $nickname
  * @throws Exception
  * @return void
  */
 public function setNickname($nickname)
 {
     if (!sjcl::isValid($nickname)) {
         throw new Exception('Invalid data.', 66);
     }
     $this->_data->meta->nickname = $nickname;
     // 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.)
     $vh = new vizhash16x16();
     $pngdata = $vh->generate(trafficlimiter::getIp());
     if ($pngdata != '') {
         $this->_data->meta->vizhash = 'data:image/png;base64,' . base64_encode($pngdata);
     }
     // Once the avatar is generated, we do not keep the IP address, nor its hash.
 }