Merge branch 'master' into burnafterreading-fix, regression in expired paste error

This commit is contained in:
El RIDO 2018-04-30 20:01:38 +02:00
commit caf87cc6f1
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
86 changed files with 3901 additions and 1586 deletions

View file

@ -7,13 +7,14 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;
use Exception;
use PDO;
use PrivateBin\Persistence\DataStore;
/**
* Configuration
@ -50,8 +51,9 @@ class Configuration
'languageselection' => false,
'languagedefault' => '',
'urlshortener' => '',
'qrcode' => true,
'icon' => 'identicon',
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer; sandbox allow-same-origin allow-scripts allow-forms allow-popups',
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; media-src data:; object-src data:; Referrer-Policy: \'no-referrer\'; sandbox allow-same-origin allow-scripts allow-forms allow-popups',
'zerobincompatibility' => false,
),
'expire' => array(
@ -99,7 +101,20 @@ class Configuration
public function __construct()
{
$config = array();
$configFile = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini';
$configFile = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php';
$configIni = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini';
// rename INI files to avoid configuration leakage
if (is_readable($configIni)) {
DataStore::prependRename($configIni, $configFile, ';');
// cleanup sample, too
$configIniSample = $configIni . '.sample';
if (is_readable($configIniSample)) {
DataStore::prependRename($configIniSample, PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php', ';');
}
}
if (is_readable($configFile)) {
$config = parse_ini_file($configFile, true);
foreach (array('main', 'model', 'model_options') as $section) {
@ -108,6 +123,7 @@ class Configuration
}
}
}
$opts = '_options';
foreach (self::getDefaults() as $section => $values) {
// fill missing sections with default values

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Data;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Data;
@ -693,9 +693,8 @@ class Database extends AbstractData
'CREATE INDEX IF NOT EXISTS comment_parent ON ' .
self::_sanitizeIdentifier('comment') . '(pasteid);'
);
// no break, continue with updates for 0.22
case '0.22':
case '1.0':
// no break, continue with updates for 0.22 and later
default:
self::_exec(
'UPDATE ' . self::_sanitizeIdentifier('config') .
' SET value = ? WHERE id = ?',

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Data;
@ -57,7 +57,7 @@ class Filesystem extends AbstractData
public function create($pasteid, $paste)
{
$storagedir = self::_dataid2path($pasteid);
$file = $storagedir . $pasteid;
$file = $storagedir . $pasteid . '.php';
if (is_file($file)) {
return false;
}
@ -79,9 +79,7 @@ class Filesystem extends AbstractData
if (!$this->exists($pasteid)) {
return false;
}
$paste = json_decode(
file_get_contents(self::_dataid2path($pasteid) . $pasteid)
);
$paste = DataStore::get(self::_dataid2path($pasteid) . $pasteid . '.php');
if (property_exists($paste->meta, 'attachment')) {
$paste->attachment = $paste->meta->attachment;
unset($paste->meta->attachment);
@ -104,8 +102,8 @@ class Filesystem extends AbstractData
$pastedir = self::_dataid2path($pasteid);
if (is_dir($pastedir)) {
// Delete the paste itself.
if (is_file($pastedir . $pasteid)) {
unlink($pastedir . $pasteid);
if (is_file($pastedir . $pasteid . '.php')) {
unlink($pastedir . $pasteid . '.php');
}
// Delete discussion if it exists.
@ -133,7 +131,26 @@ class Filesystem extends AbstractData
*/
public function exists($pasteid)
{
return is_file(self::_dataid2path($pasteid) . $pasteid);
$basePath = self::_dataid2path($pasteid) . $pasteid;
$pastePath = $basePath . '.php';
// convert to PHP protected files if needed
if (is_readable($basePath)) {
DataStore::prependRename($basePath, $pastePath);
// convert comments, too
$discdir = self::_dataid2discussionpath($pasteid);
if (is_dir($discdir)) {
$dir = dir($discdir);
while (false !== ($filename = $dir->read())) {
if (substr($filename, -4) !== '.php' && strlen($filename) >= 16) {
$commentFilename = $discdir . $filename . '.php';
DataStore::prependRename($discdir . $filename, $commentFilename);
}
}
$dir->close();
}
}
return is_readable($pastePath);
}
/**
@ -149,7 +166,7 @@ class Filesystem extends AbstractData
public function createComment($pasteid, $parentid, $commentid, $comment)
{
$storagedir = self::_dataid2discussionpath($pasteid);
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid;
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
if (is_file($file)) {
return false;
}
@ -171,15 +188,14 @@ class Filesystem extends AbstractData
$comments = array();
$discdir = self::_dataid2discussionpath($pasteid);
if (is_dir($discdir)) {
// Delete all files in discussion directory
$dir = dir($discdir);
while (false !== ($filename = $dir->read())) {
// Filename is in the form pasteid.commentid.parentid:
// Filename is in the form pasteid.commentid.parentid.php:
// - 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)
if (is_file($discdir . $filename)) {
$comment = json_decode(file_get_contents($discdir . $filename));
$comment = DataStore::get($discdir . $filename);
$items = explode('.', $filename);
// Add some meta information not contained in file.
$comment->id = $items[1];
@ -211,7 +227,7 @@ class Filesystem extends AbstractData
{
return is_file(
self::_dataid2discussionpath($pasteid) .
$pasteid . '.' . $commentid . '.' . $parentid
$pasteid . '.' . $commentid . '.' . $parentid . '.php'
);
}
@ -253,7 +269,14 @@ class Filesystem extends AbstractData
continue;
}
$thirdLevel = array_filter(
scandir($path),
array_map(
function ($filename) {
return strlen($filename) >= 20 ?
substr($filename, 0, -4) :
$filename;
},
scandir($path)
),
'PrivateBin\\Model\\Paste::isValidId'
);
if (count($thirdLevel) == 0) {

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;
@ -64,7 +64,7 @@ class Filter
$i = 0;
while (($size / 1024) >= 1) {
$size = $size / 1024;
$i++;
++$i;
}
return number_format($size, ($i ? 2 : 0), '.', ' ') . ' ' . I18n::_($iec[$i]);
}
@ -82,7 +82,7 @@ class Filter
public static function slowEquals($a, $b)
{
$diff = strlen($a) ^ strlen($b);
for ($i = 0; $i < strlen($a) && $i < strlen($b); $i++) {
for ($i = 0; $i < strlen($a) && $i < strlen($b); ++$i) {
$diff |= ord($a[$i]) ^ ord($b[$i]);
}
return $diff === 0;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Model;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Model;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Model;
@ -48,6 +48,11 @@ class Paste extends AbstractModel
$data->meta->remaining_time = $data->meta->expire_date - time();
}
// check if non-expired burn after reading paste needs to be deleted
if (property_exists($data->meta, 'burnafterreading') && $data->meta->burnafterreading) {
$this->delete();
}
// set formatter for for the view.
if (!property_exists($data->meta, 'formatter')) {
// support < 0.21 syntax highlighting

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Persistence;

View file

@ -22,6 +22,13 @@ use PrivateBin\Json;
*/
class DataStore extends AbstractPersistence
{
/**
* first line in file, to protect its contents
*
* @const string
*/
const PROTECTION_LINE = '<?php http_response_code(403); /*';
/**
* store the data
*
@ -38,10 +45,45 @@ class DataStore extends AbstractPersistence
$filename = substr($filename, strlen($path));
}
try {
self::_store($filename, Json::encode($data));
self::_store($filename, self::PROTECTION_LINE . PHP_EOL . Json::encode($data));
return true;
} catch (Exception $e) {
return false;
}
}
/**
* get the data
*
* @access public
* @static
* @param string $filename
* @return stdClass|false $data
*/
public static function get($filename)
{
return json_decode(substr(file_get_contents($filename), strlen(self::PROTECTION_LINE . PHP_EOL)));
}
/**
* rename a file, prepending the protection line at the beginning
*
* @access public
* @static
* @param string $srcFile
* @param string $destFile
* @param string $prefix (optional)
* @return void
*/
public static function prependRename($srcFile, $destFile, $prefix = '')
{
// don't overwrite already converted file
if (!is_readable($destFile)) {
$handle = fopen($srcFile, 'r', false, stream_context_create());
file_put_contents($destFile, $prefix . self::PROTECTION_LINE . PHP_EOL);
file_put_contents($destFile, $handle, FILE_APPEND);
fclose($handle);
}
unlink($srcFile);
}
}

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Persistence;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Persistence;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin\Persistence;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;
@ -28,7 +28,7 @@ class PrivateBin
*
* @const string
*/
const VERSION = '1.1';
const VERSION = '1.1.1';
/**
* minimal required PHP version
@ -147,10 +147,7 @@ class PrivateBin
);
break;
case 'read':
// reading paste is disallowed in HTML display
if ($this->_request->isJsonApiCall()) {
$this->_read($this->_request->getParam('pasteid'));
}
$this->_read($this->_request->getParam('pasteid'));
break;
case 'jsonld':
$this->_jsonld($this->_request->getParam('jsonld'));
@ -179,8 +176,7 @@ class PrivateBin
$this->_conf = new Configuration;
$this->_model = new Model($this->_conf);
$this->_request = new Request;
$this->_urlBase = array_key_exists('REQUEST_URI', $_SERVER) ?
htmlspecialchars($_SERVER['REQUEST_URI']) : '/';
$this->_urlBase = $this->_request->getRequestUri();
ServerSalt::setPath($this->_conf->getKey('dir', 'traffic'));
// set default language
@ -370,12 +366,15 @@ class PrivateBin
try {
$paste = $this->_model->getPaste($dataid);
if ($paste->exists()) {
$data = $paste->get();
$this->_doesExpire = property_exists($data, 'meta') && property_exists($data->meta, 'expire_date');
if (property_exists($data->meta, 'salt')) {
unset($data->meta->salt);
// reading paste is only possible via JSON call
if ($this->_request->isJsonApiCall()) {
$data = $paste->get();
$this->_doesExpire = property_exists($data, 'meta') && property_exists($data->meta, 'expire_date');
if (property_exists($data->meta, 'salt')) {
unset($data->meta->salt);
}
$this->_data = json_encode($data);
}
$this->_data = json_encode($data);
} else {
$this->_error = self::GENERIC_ERROR;
}
@ -429,7 +428,6 @@ class PrivateBin
$page = new View;
$page->assign('NAME', $this->_conf->getKey('name'));
$page->assign('CIPHERDATA', $this->_data);
$page->assign('ERROR', I18n::_($this->_error));
$page->assign('STATUS', I18n::_($this->_status));
$page->assign('VERSION', self::VERSION);
@ -451,6 +449,7 @@ class PrivateBin
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
$page->assign('EXPIRECLONE', !$this->_doesExpire || ($this->_doesExpire && $this->_conf->getKey('clone', 'expire')));
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
$page->assign('QRCODE', $this->_conf->getKey('qrcode'));
$page->draw($this->_conf->getKey('template'));
}

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;
@ -141,7 +141,20 @@ class Request
*/
public function getParam($param, $default = '')
{
return array_key_exists($param, $this->_params) ? $this->_params[$param] : $default;
return array_key_exists($param, $this->_params) ?
$this->_params[$param] : $default;
}
/**
* Get request URI
*
* @access public
* @return string
*/
public function getRequestUri()
{
return array_key_exists('REQUEST_URI', $_SERVER) ?
htmlspecialchars($_SERVER['REQUEST_URI']) : '/';
}
/**

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;

View file

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.1
* @version 1.1.1
*/
namespace PrivateBin;

View file

@ -8,7 +8,7 @@
* @link http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 0.0.5 beta PrivateBin 1.1
* @version 0.0.5 beta PrivateBin 1.1.1
*/
namespace PrivateBin;