introduce option to disable vizhash for paranoid admins, resolves #20 point 2.4

This commit is contained in:
El RIDO 2016-07-18 10:14:38 +02:00
parent 20cf678a75
commit ff0c55c0d6
5 changed files with 83 additions and 11 deletions

View File

@ -53,6 +53,12 @@ languageselection = false
; the pastes encryption key ; the pastes encryption key
; urlshortener = "https://shortener.example.com/api?link=" ; urlshortener = "https://shortener.example.com/api?link="
; (optional) vizhash is a weak mechanism to detect if a comment was from a
; different user when the same username was used in a comment. It is based on
; the IP and might be used to get the posters IP if the server salt is leaked
; and a rainbow table is generated for all IPs. Enabled by default.
; vizhash = false
; stay compatible with PrivateBin Alpha 0.19, less secure ; stay compatible with PrivateBin Alpha 0.19, less secure
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of ; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
; sha256 in HMAC for the deletion token ; sha256 in HMAC for the deletion token

View File

@ -44,6 +44,7 @@ class configuration
'languageselection' => false, 'languageselection' => false,
'languagedefault' => '', 'languagedefault' => '',
'urlshortener' => '', 'urlshortener' => '',
'vizhash' => true,
'zerobincompatibility' => false, 'zerobincompatibility' => false,
), ),
'expire' => array( 'expire' => array(

View File

@ -174,6 +174,8 @@ class model_comment extends model_abstract
if (!sjcl::isValid($nickname)) throw new Exception('Invalid data.', 66); if (!sjcl::isValid($nickname)) throw new Exception('Invalid data.', 66);
$this->_data->meta->nickname = $nickname; $this->_data->meta->nickname = $nickname;
if ($this->_conf->getKey('vizhash'))
{
// Generation of the anonymous avatar (Vizhash): // Generation of the anonymous avatar (Vizhash):
// If a nickname is provided, we generate a Vizhash. // If a nickname is provided, we generate a Vizhash.
// (We assume that if the user did not enter a nickname, he/she wants // (We assume that if the user did not enter a nickname, he/she wants
@ -186,4 +188,5 @@ class model_comment extends model_abstract
} }
// Once the avatar is generated, we do not keep the IP address, nor its hash. // Once the avatar is generated, we do not keep the IP address, nor its hash.
} }
}
} }

View File

@ -325,6 +325,13 @@ class privatebin_db extends privatebin_abstract
*/ */
public function createComment($pasteid, $parentid, $commentid, $comment) public function createComment($pasteid, $parentid, $commentid, $comment)
{ {
foreach (array('nickname', 'vizhash') as $key)
{
if (!array_key_exists($key, $comment['meta']))
{
$comment['meta'][$key] = null;
}
}
return self::_exec( return self::_exec(
'INSERT INTO ' . self::_sanitizeIdentifier('comment') . 'INSERT INTO ' . self::_sanitizeIdentifier('comment') .
' VALUES(?,?,?,?,?,?,?)', ' VALUES(?,?,?,?,?,?,?)',
@ -367,9 +374,9 @@ class privatebin_db extends privatebin_abstract
$comments[$i]->data = $row['data']; $comments[$i]->data = $row['data'];
$comments[$i]->meta = new stdClass; $comments[$i]->meta = new stdClass;
$comments[$i]->meta->postdate = (int) $row['postdate']; $comments[$i]->meta->postdate = (int) $row['postdate'];
if (array_key_exists('nickname', $row)) if (array_key_exists('nickname', $row) && !empty($row['nickname']))
$comments[$i]->meta->nickname = $row['nickname']; $comments[$i]->meta->nickname = $row['nickname'];
if (array_key_exists('vizhash', $row)) if (array_key_exists('vizhash', $row) && !empty($row['vizhash']))
$comments[$i]->meta->vizhash = $row['vizhash']; $comments[$i]->meta->vizhash = $row['vizhash'];
} }
ksort($comments); ksort($comments);

View File

@ -208,4 +208,59 @@ class modelTest extends PHPUnit_Framework_TestCase
$paste->store(); $paste->store();
$paste->getComment(helper::getPasteId())->delete(); $paste->getComment(helper::getPasteId())->delete();
} }
public function testCommentWithDisabledVizhash()
{
$options = parse_ini_file(CONF, true);
$options['main']['vizhash'] = false;
$options['model'] = array(
'class' => 'privatebin_db',
);
$options['model_options'] = array(
'dsn' => 'sqlite::memory:',
'usr' => null,
'pwd' => null,
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
);
helper::confBackup();
helper::createIniFile(CONF, $options);
$model = new model(new configuration);
$pasteData = helper::getPaste();
$this->_model->getPaste(helper::getPasteId())->delete();
$paste = $model->getPaste(helper::getPasteId());
$this->assertFalse($paste->exists(), 'paste does not yet exist');
$paste = $model->getPaste();
$paste->setData($pasteData['data']);
$paste->setOpendiscussion();
$paste->setFormatter($pasteData['meta']['formatter']);
$paste->store();
$paste = $model->getPaste(helper::getPasteId());
$this->assertTrue($paste->exists(), 'paste exists after storing it');
$paste = $paste->get();
$this->assertEquals($pasteData['data'], $paste->data);
foreach (array('opendiscussion', 'formatter') as $key) {
$this->assertEquals($pasteData['meta'][$key], $paste->meta->$key);
}
// storing comments
$commentData = helper::getComment();
$paste = $model->getPaste(helper::getPasteId());
$comment = $paste->getComment(helper::getPasteId(), helper::getCommentId());
$this->assertFalse($comment->exists(), 'comment does not yet exist');
$comment = $paste->getComment(helper::getPasteId());
$comment->setData($commentData['data']);
$comment->setNickname($commentData['meta']['nickname']);
$comment->store();
$comment = $paste->getComment(helper::getPasteId(), helper::getCommentId());
$this->assertTrue($comment->exists(), 'comment exists after storing it');
$comment = $comment->get();
$this->assertEquals($commentData['data'], $comment->data);
$this->assertEquals($commentData['meta']['nickname'], $comment->meta->nickname);
$this->assertFalse(property_exists($comment->meta, 'vizhash'), 'vizhash was not generated');
}
} }