fork from production

hash-command-arbitrary
Avril 5 years ago
commit 0e3b24a641

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

@ -0,0 +1,103 @@
<?PHP
#error_reporting(E_ALL);
// Examples:
// $str = base85::encode("Hello world!");
// $str = base85::decode(":e4D*;K$&\Er");
class base85
{
public static function decode($str) {
$str = preg_replace("/ \t\r\n\f/","",$str);
$str = preg_replace("/z/","!!!!!",$str);
$str = preg_replace("/y/","+<VdL/",$str);
// Pad the end of the string so it's a multiple of 5
$padding = 5 - (strlen($str) % 5);
if (strlen($str) % 5 === 0) {
$padding = 0;
}
$str .= str_repeat('u',$padding);
$num = 0;
$ret = '';
// Foreach 5 chars, convert it to an integer
while ($chunk = substr($str, $num * 5, 5)) {
$tmp = 0;
foreach (unpack('C*',$chunk) as $item) {
$tmp *= 85;
$tmp += $item - 33;
}
// Convert the integer in to a string
$ret .= pack('N', $tmp);
$num++;
}
// Remove any padding we had to add
$ret = substr($ret,0,strlen($ret) - $padding);
return $ret;
}
public static function encode($str) {
$ret = '';
$debug = 0;
$padding = 4 - (strlen($str) % 4);
if (strlen($str) % 4 === 0) {
$padding = 0;
}
if ($debug) {
printf("Length: %d = Padding: %s<br /><br />\n",strlen($str),$padding);
}
// If we don't have a four byte chunk, append \0s
$str .= str_repeat("\0", $padding);
foreach (unpack('N*',$str) as $chunk) {
// If there is an all zero chunk, it has a shortcut of 'z'
if ($chunk == "\0") {
$ret .= "z";
continue;
}
// Four spaces has a shortcut of 'y'
if ($chunk == 538976288) {
$ret .= "y";
continue;
}
if ($debug) {
var_dump($chunk); print "<br />\n";
}
// Convert the integer into 5 "quintet" chunks
for ($a = 0; $a < 5; $a++) {
$b = intval($chunk / (pow(85,4 - $a)));
$ret .= chr($b + 33);
if ($debug) {
printf("%03d = %s <br />\n",$b,chr($b+33));
}
$chunk -= $b * pow(85,4 - $a);
}
}
// If we added some null bytes, we remove them from the final string
if ($padding) {
$ret = preg_replace("/z$/",'!!!!!',$ret);
$ret = substr($ret,0,strlen($ret) - $padding);
}
return $ret;
}
} // End of base85 class

@ -0,0 +1,152 @@
<?php
require_once "/main.inc";
class Encryption
{
public $publicKey=null;
public $privateKey=null;
private $res=null;
private $dt=null;
private $psk=null;
private $upsk=false;
private static $sklen = 4096;
private static $config = array(
"digest_alg" => "sha512",
"private_key_bits" => 4096,
"private_key_type"=> OPENSSL_KEYTYPE_RSA,
);
private function generateNewSymmetricKey()
{
return openssl_random_pseudo_bytes(self::$sklen);
}
private function _begin($prec)
{
$this->res = openssl_pkey_new(self::$config);
openssl_pkey_export($this->res, $this->publicKey);
$this->dt=openssl_pkey_get_details($this->res);
$this->publicKey=$this->dt["key"];
if($prec)
{
$this->upsk = true;
$this->psk = generateNewSymmetricKey();
}
}
public function __construct()
{
$this->_begin(false);
}
public function __construct1($p)
{
$this->_begin($p);
}
private function s_decrypt($data, $key)
{
return s_encrypt($data, $key); //same;
}
private function s_encrypt($data, $key)
{
$j=0;
$out = "";
for($i=0;$i<strlen($data);$i++)
{
if($j>=strlen($key)) $j=0;
$out .= ($data[$i] ^ $key[$j]);
$j+=1;
}
return $out;
}
public function encrypt($data)
{
$skey = ($this->upsk?$this->psk:$this->generateNewSymmetricKey());
$e_skey = null;
openssl_public_encrypt($skey, $e_skey, $this->publicKey);
$e_data = $this->s_encrypt($data, $skey);
return CreateFromEncryption(array("ekey"=>$e_skey, "edata"=>$e_data));
}
public function decrypt(EncryptedData $ed)
{
$ekey = $ed->e_symmetricKey();
$edata = $ed->e_data();
$skey = null;
openssl_private_decrypt($ekey, $skey, $this->privateKey);
return $this->s_decrypt($edata, $skey);
}
public function encdata_create($data)
{
return EncryptedData::CreateFromData($data);
}
}
class EncryptedData
{
private $ekey=null;
private $edata=null;
private function __construct(Array $data)
{
$this->ekey = $data["ekey"];
$this->edata = $data["edata"];
}
public function __construct1($ek, $ed)
{
$this->ekey = $ek;
$this->edata = $ed;
}
private function __construct2()
{
}
public function binaryData($set=null)
{
if($set==null) {
return "{".strlen($this->ekey).", ".strlen($this->edata)."}".$this->ekey.$this->edata;
}
else
{
$kvals = explode(", ", substr(substr($set, 0, strpos($set, "}")), 1));
$klen = intval($kvals[0]);
$dlen = intval($kvals[1]);
$this->ekey = substr($set, strpos($set, "}")+1, $klen);
$this->edata = substr($set, strpos($set, "}")+1+$klen, $dlen);
}
}
public function e_symmetricKey($val=null)
{
if($val==null) {
return $this->ekey;
}
else
{
$this->ekey = $val;
}
}
public function e_data($val=null)
{
if($val==null) {
return $this->edata;
}
else
{
$this->edata = $val;
}
}
public static function CreateFromData($data)
{
$val = new EncryptedData();
$val->binaryData($data);
return $val;
}
public static function CreateFromEncryption(Array $data)
{
return new EncryptedData($data);
}
}
?>

@ -0,0 +1,651 @@
<?php
define('TIMEALLOWED', (60*15));
define('TIME_MINUTE', (60));
define('TIME_HOUR', (60*60));
define('TIME_DAY', (60*60*24));
define('TIME_WEEK', (60*60*24*7));
define('TIME_MONTH', (60*60*24*7*5));
define('TIME_YEAR', (60*60*24*365));
define("SQL_DEFAULT_HOST_NAME", "localhost");
define("SQL_DEFAULT_USER", "root");
define("SQL_DEFAULT_PASSWORD", "root");
if(isLogForce()) doLoggerOnce();
if(isForced())
{
if(isBanned(getip())) die();
if(!isActive())
{
if(getAdminLevel(getip())===false) die();
}
}
function setForceLog($fl)
{
file_put_contents("/forcelog", $fl?"true":"false");
}
function isLogForce()
{
$ar = file_get_contents("/forcelog");
return streq($ar,"true");
}
function bcrypt_verify($name, $hash)
{
return bcrypt($name) == $hash;
}
function bcrypt($str)
{
return crypt($str, '_J9..rasm');
}
function pa($str)
{
$out="";
$col="";
$level==0;
$fonttags=0;
$vr=0;
for($i=0;$i<strlen($str);$i++)
{
if($str[$i] == "\n")
{
if($level==1) {
$out .="<font color=#$col>";
$vr+=1;
$col="";
$level-=1;
}
else
$level+=1;
}
elseif($level==1)
{
$col.=$str[$i];
}
else {
$out.=$str[$i];
}
}
return $out.str_repeat("</font>", $vr);
}
function phplib($nm)
{
require_once "/phplib/$nm";
}
function jtostring($val)
{
$out = "{";
$keys = array_keys($val);
for($i=0;$i<count($keys);$i++)
{
$key = is_array($keys[$i])?jtostring($keys[$i]):$keys[$i];
$value = is_array($val[$keys[$i]])?jtostring($val[$keys[$i]]):$val[$keys[$i]];
$out .= "[$key] = [$value]".(($i==(count($keys)-1))?"":", ");
}
return $out . "}";
}
function setupNotifications()
{
jslib("notify.js");
}
function isActive()
{
return streq(file_get_contents("/active"), "true");
}
function getLastMember($array)
{
$el = end($array);
reset($array);
return $el;
}
function arraydup($ar)
{
return unserialize(serialize($ar));
}
function getSessionInfo($ip=null)
{
$sql = beginSQL("server");
$res = mysql_query_return_assoc("SELECT * FROM sessionInfo ".($ip!=null?"WHERE `ip` = '$ip' ":"")."LIMIT 0, 1");
$ret=null;
if($res!==false)
{
$ret = $res;
}
@mysql_free_result_array($res);
endSQL($sql);
return $ret;
}
function defaultNotify()
{
notifyBar("__user_message");
notifyBar("__temp_message");
notifyBar("__get_message");
notifyBar("__server_message");
if(isset($_REQUEST["msg"]))
js("setNotifyBar('#__get_message', '".$_REQUEST["msg"]."', 2000);");
js("defnot_set_load_user_message(\"".getip()."\");
defnot_set_load_server_message();");
}
function startsWith($haystack, $needle) {
// search backwards starting from haystack length characters from the end
return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
}
function endsWith($haystack, $needle) {
// search forward starting from end minus needle length characters
return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== FALSE);
}
function checkTempNotify()
{
if(tempNotifyExists())
{
$vl = readTempNotify();
js("setNotifyBar('#__temp_message', '".addslashes($vl)."', 3000);");
}
}
function notifyBar($id)
{
echo("<div class='none' style='font-family: Consolas; font-size: 20px; text-align: center' id='$id'></div>");
}
function getifexists($ar, $vl)
{
if(isset($ar[$vl])) return $ar[$vl];
else return null;
}
function jserialise($ar) {return jsserialise($ar);}
function jsserialise($ar)
{
$keys = array_keys($ar);
$values = array_values($ar);
$out = "";
for($i=0;$i<count($values);$i++)
{
$key = (is_array($keys[$i])?"array_".base64_encode(jsserialise($keys[$i])):base64_encode($keys[$i]));
$value = (is_array($values[$i])?"array_".base64_encode(jsserialise($values[$i])):base64_encode($values[$i]));
$out .= "$key-$value\r\n";
}
return $out;
}
function setForced($vl)
{
file_put_contents("/force", $vl?"true":"false");
}
function isForced()
{
return streq(file_get_contents("/force"), "true");
}
function readUntil($str, $c)
{
$pos = strpos($str, $c);
if($pos!==false&&$pos>0)
{
return substr($str, 0, $pos-1);
}
else return $str;
}
function junserialise($ar) {return jsunserialise($ar);}
function jsunserialise($ar)
{
$ars= array();
foreach(explode("\r\n", $ar) as $line)
{
if($line!="") {
$ur = explode("-", $line);
$key = startsWith($ur[0], "array_")?junserialise(base64_decode(substr($ur[0], 6))):base64_decode($ur[0]);
$value = startsWith($ur[1], "array_")?junserialise(base64_decode(substr($ur[1], 6))):base64_decode($ur[1]);
$ars[$key] = $value;
}
}
return $ars;
}
function formatDateTime($dt)
{
if($dt<TIME_MINUTE)
return $dt." seconds ago";
elseif($dt<TIME_HOUR)
return round($dt/TIME_MINUTE)." minutes ago";
elseif($dt<TIME_DAY)
return round($dt/TIME_HOUR)." hours ago";
elseif($dt<TIME_WEEK)
return round($dt/TIME_DAY)." days ago";
elseif($dt<TIME_MONTH)
return round($dt/TIME_WEEK)." weeks ago";
elseif($dt<TIME_YEAR)
return round($dt/TIME_MONTH)." months ago";
else
return (round(($dt/TIME_YEAR)*100.00)/100.00)." years ago";
}
function jss($script)
{
echo ("<script src='$script'></script>");
}
function jslib($name)
{
jss("/jslib/$name");
}
function isBanned($ip)
{
$sql = beginSQL("server");
$res = mysql_query_return_assoc("SELECT banned FROM sessionInfo WHERE `ip`='$ip'");
$ret = $res[0]["banned"];
@mysql_free_result_array($res);
endSQL($sql);
return $ret;
}
function redirect($page,$wtime=0)
{
echo '<meta http-equiv="REFRESH" content="'.$wtime.';url='.$page.'"></HEAD>';
}
function getAdminLevel($ip)
{
$sql = beginSQL("server");
$res = mysql_query_return_assoc("SELECT `level` FROM admins WHERE `ip`='$ip'");
$ret=false;
if($res != array())
{
$ret = $res[0]["level"];
}
@mysql_free_result_array($res);
endSQL($sql);
return $ret;
}
function banUser($ip)
{
$sql = beginSQL("server");
mysql_query("UPDATE sessionInfo SET
`banned`=1
WHERE `ip`='$ip'");
endSQL($sql);
}
function unbanUser($ip)
{
$sql = beginSQL("server");
mysql_query("UPDATE sessionInfo SET
`banned`=0
WHERE `ip`='$ip'");
endSQL($sql);
}
function jquery()
{
jslib("jquery-1.8.2.js");
jslib("jquery.base64.js");
}
function js($str)
{
echo("<script>$str</script>");
}
function issetmultiple($ar, $vls)
{
$val = true;
foreach($vls as $r) $val = $val && isset($ar[$r]);
return $val;
}
function pageinit_n($sql=null)
{
pageinit($sql);
jquery();
jslib("notify.js");
enableBanCheck();
doActiveCheck();
}
function pathfix($str)
{
return str_replace("\\", "/", $str);
}
function sqldate($stamp=null)
{
return date("y.m.d H.i.s", $stamp==null?time():$stamp);
}
function enableBanCheck()
{
jslib("check.js");
js("banCheck();");
if(isBanned(getip())) doBan();
}
function activeNotifyBar($id, $val)
{
echo("<div class='notify' style='font-family: Consolas; font-size: 20px; text-align: center' id='$id'>$val</div>");
}
function doActiveCheck()
{
if(!isActive()) {
if(getAdminLevel(getip())!==false)
{
echo("<div class='notify' style='font-family: Consolas; font-size: 20px; text-align: center' id='__active_n'>WEBSITE OFFLINE</div>");
}
else
die("website offline");
}
}
function doBan()
{
redirect("/banned.php");
die();
}
function pageinit($vsql=null)
{
$sql = $vsql==null?beginSQL("server"):$vsql;
if($vsql!=null)
{
mysql_select_db("server",$sql);
}
$res = mysql_query_return_assoc("SELECT * FROM `sessionInfo` WHERE `ip`='".getip()."'");
echo(mysql_error());
if($res==array())
{
mysql_query("INSERT INTO sessionInfo (
ip, url, sessionid, last
) VALUES (
'".getip()."',
'".geturl()."',
".(sessionid()==null||streq(sessionid(),"")?"NULL":"'".$_REQUEST["PHPSESSID"]."'").",
'".date("y.m.d H:i:s")."'
)");
echo(mysql_error());
}
else
{
mysql_query("UPDATE sessionInfo SET
url='".geturl()."',
sessionid=".(sessionid()==null||streq(sessionid(),"")?"NULL":"'".$_REQUEST["PHPSESSID"]."'").",
last='".date("y.m.d H:i:s")."',
views=views+1
WHERE
`ip`='".getip()."'
");
echo(mysql_error());
}
@mysql_free_result_array($res);
doLogger();
if($vsql==null) endSQL($sql);
}
function doLoggerOnce()
{
$sql = beginSQL("server");
doLogger();
endSQL($sql);
}
function setLogAll($l)
{
file_put_contents("/logall", $l?"true":"false");
}
function isLogAll()
{
return streq(file_get_contents("/logall"), "true")?true:false;
}
function js_onKeyPress($id, $func, $key)
{
js('$(document).ready(function()
{
$("'.$id.'").keypress(function (e){
if(e.keyCode=='.$key.')
'.$func.';
});
});');
}
function js_onEnterPress($id, $func)
{
js_onKeyPress($id, $func, 13);
}
function doLogger()
{
$r = mysql_query_return_assoc("SELECT * FROM logInfo WHERE `ip`='".getip()."'");
if(($r!=array())||isLogAll())
{
mysql_query("INSERT INTO logs (
ip, url, session, time
) VALUES (
'".getip()."',
'".geturl()."',
".(sessionid()==null||streq(sessionid(),"")?"NULL":"'".$_REQUEST["PHPSESSID"]."'").",
'".sqldate()."'
)");
}
else @mysql_free_result_array($r);
}
function writeAllText($fn, $txt)
{
$p = fopen($fn, "w");
fwrite($p, $txt);
fclose($p);
}
function sessionid()
{
return $_REQUEST["PHPSESSID"];
}
function geturl() {
$actual_link = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
return $actual_link;
}
function getmsg()
{
$txt = @readalltext("\message");
if(streq($txt,"")) return NULL;
return $txt;
}
function button($value, $onclick=null,$other="")
{
echo("<input type='button' value='$value' ".($onclick==null?"":"onclick='$onclick' ")." $other />");
}
function sessionActive()
{
return sessionid() !== '';
}
function setTempNotify($msg)
{
$_SESSION["msg"]=$msg;
}
function tempNotifyExists()
{
return isset($_SESSION["msg"]);
}
function readTempNotify()
{
$msg=null;
if(isset($_SESSION["msg"])) {
$msg = $_SESSION["msg"];
unset($_SESSION["msg"]);
}
return $msg;
}
function index($ar, $i)
{
return $ar[$i];
}
function mysql_query_return_assoc($q)
{
$res = (mysql_query($q));
$ret=array();
$i=0;
if(!$res) echo(mysql_error());
else
while($cur = mysql_fetch_assoc($res))
{
$ret[$i++] = $cur;
}
//mysql_free_result($q);
return $ret;
}
function readAllText($fn)
{
$fp = fopen($fn,"r");
$data = fread($fp, filesize($fn));
fclose($fp);
return $data;
}
function beginSQL($db)
{
$con = mysql_connect(SQL_DEFAULT_HOST_NAME, SQL_DEFAULT_USER, SQL_DEFAULT_PASSWORD);
mysql_select_db($db, $con);
return $con;
}
function endSQL($con)
{
mysql_close($con);
}
function css($css)
{
echo '<LINK href="'.$css.'" rel="stylesheet" type="text/css">';
}
function css_main($dir="/")
{
echo '<LINK href="'.$dir.'css/main.css" rel="stylesheet" type="text/css">';
}
function title($title, $others="",$id=null)
{
echo "<p id='center' $others class='title' ".($id==null?"":"id='".$id."'").">$title</p>\n";
echo "<title>$title</title>";
}
function mysql_free_result_array($res)
{
foreach($res as $re)
mysql_free_result($re);
}
function lb()
{
echo("<br />");
}
function para()
{
echo("<p />");
}
function validip($ip)
{
return preg_match("~([0-9]{1,3}[.]){3,3}[0-9]{1,3}~",$ip);
}
function getip()
{
if (validip($_SERVER["HTTP_CLIENT_IP"])) {
return $_SERVER["HTTP_CLIENT_IP"];
}
foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) {
if (validip(trim($ip))) {
return $ip;
}
}
if (validip($_SERVER["HTTP_X_FORWARDED"])) {
return $_SERVER["HTTP_X_FORWARDED"];
} elseif (validip($_SERVER["HTTP_FORWARDED_FOR"])) {
return $_SERVER["HTTP_FORWARDED_FOR"];
} elseif (validip($_SERVER["HTTP_FORWARDED"])) {
return $_SERVER["HTTP_FORWARDED"];
} elseif (validip($_SERVER["HTTP_X_FORWARDED"])) {
return $_SERVER["HTTP_X_FORWARDED"];
} else {
return $_SERVER["REMOTE_ADDR"];
}
}
function link_tab($res, $txt, $other="")
{
link($res, $txt, "target='_black' ".$other);
}
function link($res, $txt, $other="")
{
echo("<a $other href='$res'>$txt</a>");
}
function streq($str,$str2)
{
return strcmp($str,$str2)==0;
}
function echoline($ln)
{
echo($ln); lb();
}
function echopara($pa)
{
echo($pa); para();
}
class Session {
public static function unserialize($session_data) {
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
public static function serialize( $array, $safe = true ) {
// the session is passed as refernece, even if you dont want it to
if( $safe )
$array = unserialize(serialize( $array )) ;
//var_dump($array);
$raw = '' ;
$line = 0 ;
$keys = array_keys( $array ) ;
foreach( $keys as $key ) {
$value = $array[ $key ] ;
$line ++ ;
$raw .= $key .'|' ;
if( is_array( $value ) && isset( $value['huge_recursion_blocker_we_hope'] )) {
$raw .= 'R:'. $value['huge_recursion_blocker_we_hope'] . ';' ;
} else {
$raw .= serialize( $value ) ;
}
$array[$key] = Array( 'huge_recursion_blocker_we_hope' => $line ) ;
}
return $raw ;
}
}
?>

@ -0,0 +1,71 @@
<?php
require_once "/main.inc";
define("CHUNKSIZE", 512);
function imagexy($im)
{
return array(imagesx($im), imagesy($im));
}
class ImageScrambler
{
public $source=null;
public $seed=null;
public function __construct($image, $rndr)
{
$this->source=$image;
$this->seed = $rndr;
srand($rndr);
}
private function getAreas()
{
$v = imagexy($this->source);
$xv = $v[0] % CHUNKSIZE;
$yv = $v[1] % CHUNKSIZE;
$ret = array();
$i=0;
for($y=0;$i<$yv;$y++)
{
for($x=0;$x<$xv;$x++)
{
$ret[$i++] = array($x*CHUNKSIZE, $y*CHUNKSIZE,CHUNKSIZE,CHUNKSIZE);
}
}
return $ret;
}
private function _swap($ar,$i,$j)
{
$cp = $ar[$i];
$ar[$i] = $ar[$j];
$ar[$j] = $cp;
}
private function scrambleArea($ar)
{
for($i=count($ar)-1;$i>=0;$i--)
{
$this->_swap($ar, $i, rand(0, $i));
}
return $ar;
}
public function scramble()
{
$area = $this->getAreas();
$sarea = $this->scrambleArea($area);
$nw = imagecreate(imagesx($this->source), imagesy($this->source));
for($i=0;count($area);$i+=2)
{
imagecopy($nw, $this->source, $sarea[$i+1][0], $sarea[$i+1][1], $sarea[$i][0], $sarea[$i][1],CHUNKSIZE,CHUNKSIZE);
}
imagedestroy($this->source);
$this->source=$nw;
return $sarea;
}
public function destroy()
{
imagedestroy($this->$source);
}
}
?>

@ -0,0 +1,18 @@
<?php
require_once "/main.inc";
function _plist_isName($name, $val)
{
return password_verify($name, $val);
}
function _plist_name($nm) {
return bcrypt($nm);
}
function plist_add($name, $value)
{
$val = _plist_name($name);
}
?>

@ -0,0 +1,119 @@
<?php
require_once "/main.inc";
function mp4video($file) {
$fp = @fopen($file, 'rb');
$size = filesize($file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
header('Content-type: video/mp4');
//header("Accept-Ranges: 0-$length");
header("Accept-Ranges: bytes");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);
$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
}
function webmvideo($file) {
$fp = @fopen($file, 'rb');
$size = filesize($file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
header('Content-type: video/webm');
//header("Accept-Ranges: 0-$length");
header("Accept-Ranges: bytes");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);
$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
}
?>

@ -0,0 +1,3 @@
[Trash Info]
Path=static/www/.file
DeletionDate=2018-07-07T16:06:51

@ -0,0 +1,3 @@
[Trash Info]
Path=rtbw/Untitled%20Folder
DeletionDate=2018-08-29T14:14:52

@ -0,0 +1,3 @@
[Trash Info]
Path=rtbw/Untitled%20Folder
DeletionDate=2018-08-13T18:01:21

@ -0,0 +1,3 @@
[Trash Info]
Path=static/www/i/bg%20%28copy%29.png
DeletionDate=2018-05-11T11:36:18

@ -0,0 +1,3 @@
[Trash Info]
Path=static/www/i/bg.png
DeletionDate=2018-05-11T11:36:13

@ -0,0 +1,3 @@
[Trash Info]
Path=rtbw/maintain/ctl.js
DeletionDate=2018-08-29T14:15:18

@ -0,0 +1,3 @@
[Trash Info]
Path=static/old
DeletionDate=2018-05-11T10:07:58

37
.gitignore vendored

@ -0,0 +1,37 @@
static/
git/
rtbw/
www.old/
www/.*/
api/
www/favicon.ico
*.node
*.pid
*.swp
.build
.lock*
.DS_Store
authdump
config.js
graveyard
error.log
findapng
hot.js
jsmin
node_modules/
package-lock.json
perceptual
imager/tmp
state
tripcode/.build
tripcode/build
upkeep/credentials.json
voice/*.mp3
www/archive
www/js/client*.js
www/js/vendor*.js
www/src
www/thumb
www/mid
www/vint

@ -0,0 +1,19 @@
Copyright (C) 2010-2017 Lal'C Mellk Mal
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,14 @@
all:
$(MAKE) -C imager
$(MAKE) -C tripcode
client:
@echo 'make client' is no longer necessary
@false
.PHONY: all clean client
clean:
rm -rf -- .build state www/js/{client,vendor}{.,-}*.js
$(MAKE) -C imager -w clean
$(MAKE) -C tripcode -w clean

@ -0,0 +1,50 @@
Real-time imageboard.
MIT licensed.
Setup:
* Install dependencies listed below
* Sign up for reCAPTCHA
* Create a GitHub Application (callback URL = site URL + /login)
* Copy config.js.example to config.js and configure
* Copy hot.js.example to hot.js and configure
* Copy imager/config.js.example to imager/config.js and configure
* Copy report/config.js.example to report/config.js and configure
* You might need to run `npm install -g node-gyp`
* Run `npm install` to install npm deps and compile a few helpers
* Run `node builder.js` to run an auto-reloading development server
Production:
* Have your webserver serve www/ (or wherever you've moved src, thumb, etc.)
- Configure `imager.config.MEDIA_URL` appropriately
- Then turn off `SERVE_STATIC_FILES` and `SERVE_IMAGES`
* If you're behind Cloudflare turn on `CLOUDFLARE`
- Or if you're behind any reverse proxy (nginx etc) turn on `TRUST_X_FORWARDED_FOR`
* Run `node server/server.js` for just the server
* You can update client code & hot.js on-the-fly with `node server/kill.js`
* For nginx hosting/reverse proxying, refer to docs/nginx.conf.example
* For a sample init script, refer to docs/doushio.initscript.example
* config.DAEMON support is old and broken, PRs welcome
Dependencies:
* ImageMagick
* libpng
* node.js + npm
* redis
* ffmpeg 2.2+ if supporting WebM
* jhead and jpegtran optionally, for EXIF autorotation
Optional npm deps for various features:
* ~~daemon~~ (broken currently)
* icecast now-playing banners: node-expat
* [send](https://github.com/visionmedia/send) (if you want to serve static files directly from the node.js process; useful in debug mode also)
Standalone upkeep scripts:
* archive/daemon.js - moves old threads to the archive
* upkeep/backup.js - uploads rdb to S3
* upkeep/clean.js - deletes archived images
* upkeep/radio.js - icecast2 server integration

@ -0,0 +1,5 @@
* Update `syncs` in client when on /live
* Actually tell user when a particular thread failed to sync
* Tokenize text instead of multiple levels of regexps
* Should retrieve live body and hctr in one transaction
* Consolidate or disambiguate the (three!) different hook/trigger mechanisms

@ -0,0 +1,473 @@
/* NOTE: This file is processed by server/state.js
and served by server/server.js (to auth'd users only) */
$('<link>', {rel: 'stylesheet', type: 'text/css', href: mediaURL+'css/mod.css'}).appendTo('head');
var $selectButton, $controls;
window.loggedInUser = IDENT.user;
window.x_csrf = IDENT.csrf;
function show_toolbox() {
var specs = [
{name: 'Lewd', kind: 7},
{name: 'Porn', kind: 8},
{name: 'Delete', kind: 9},
{name: 'Lock', kind: 11},
];
if (IDENT.auth == 'Admin')
specs.push({name: 'Panel', kind: 'panel'});
var $toolbox = $('<div/>', {id: 'toolbox', "class": 'mod'});
$selectButton = $('<input />', {
type: 'button', val: 'Select',
click: function (e) { toggle_multi_selecting(); },
});
$toolbox.append($selectButton, ' ');
$controls = $('<span></span>').hide();
_.each(specs, function (spec) {
$controls.append($('<input />', {
type: 'button',
val: spec.name,
data: {kind: spec.kind},
}), ' ');
});
$controls.on('click', 'input[type=button]', tool_action);
_.each(delayNames, function (when, i) {
var id = 'delay-' + when;
var $label = $('<label/>', {text: when, 'for': id});
var $radio = $('<input/>', {
id: id, type: 'radio', val: when, name: 'delay',
});
if (i == 0)
$radio.prop('checked', true);
$controls.append($radio, $label, ' ');
});
$toolbox.append($controls).insertBefore(THREAD ? 'hr:last' : $ceiling);
}
function tool_action(event) {
var ids = [];
var $sel = $('.selected');
$sel.each(function () {
var id = extract_num(parent_post($(this)));
if (id)
ids.push(id);
});
var $button = $(this);
var kind = $button.data('kind');
if (kind == 'panel')
return toggle_panel();
/* On a thread page there's only one thread to lock, so... */
if (kind == 11 && THREAD && !ids.length)
ids = [THREAD];
if (ids.length) {
var when = $('input:radio[name=delay]:checked').val();
ids.unshift(parseInt(kind, 10), {when: when});
send(ids);
$sel.removeClass('selected');
}
else {
var orig = $button.val();
var caption = _.bind($button.val, $button);
caption('Nope.');
if (orig != 'Nope.')
_.delay(caption, 2000, orig);
}
}
readOnly.push('graveyard');
menuOptions.unshift('Select');
menuHandlers.Hide = function () { alert('nope.avi'); };
var multiSelecting = false;
function toggle_multi_selecting(model, $post) {
var oldTarget;
if ($post && model) {
oldTarget = lockTarget;
set_lock_target(model.id);
}
with_dom(function () {
multiSelecting = !multiSelecting;
if (multiSelecting) {
$('body').addClass('multi-select');
make_selection_handle().prependTo('article');
make_selection_handle().prependTo('section > header');
if ($post)
select_post($post);
$controls.show();
$selectButton.val('X');
}
else {
$('body').removeClass('multi-select');
$('.select-handle').remove();
$controls.hide();
$selectButton.val('Select');
}
});
if ($post)
set_lock_target(oldTarget);
}
menuHandlers.Select = toggle_multi_selecting;
function enable_multi_selecting() {
if (!multiSelecting)
toggle_multi_selecting();
}
function select_post($post) {
$post.find('.select-handle:first').addClass('selected');
}
function make_selection_handle() {
return $('<a class="select-handle" href="#"/>');
}
window.fun = function () {
send([33, THREAD]);
};
override(ComposerView.prototype, 'make_alloc_request',
function (orig, text, img) {
var msg = orig.call(this, text, img);
if ($('#authname').is(':checked'))
msg.auth = IDENT.auth;
return msg;
});
$DOC.on('click', '.select-handle', function (event) {
event.preventDefault();
$(event.target).toggleClass('selected');
});
with_dom(function () {
$('h1').text('Moderation - ' + $('h1').text());
var $authname = $('<input>', {type: 'checkbox', id: 'authname'});
var $label = $('<label/>', {text: ' '+IDENT.auth}).prepend($authname);
$name.after(' ', $label);
/* really ought to be done with model observation! */
$authname.change(function () {
if (postForm)
postForm.propagate_ident();
});
oneeSama.hook('fillMyName', function ($el) {
var auth = $('#authname').is(':checked');
$el.toggleClass(IDENT.auth.toLowerCase(), auth);
if (auth)
$el.append(' ## ' + IDENT.auth)
});
Backbone.on('afterInsert', function (model, $el) {
if (multiSelecting)
make_selection_handle().prependTo($el);
});
show_toolbox();
});
var Address = Backbone.Model.extend({
idAttribute: 'key',
defaults: {
count: 0,
},
});
var AddressView = Backbone.View.extend({
className: 'mod address',
events: {
'keydown .name': 'entered_name',
'click .sel-all': 'select_all',
'click .ban': 'ban',
},
initialize: function () {
var $el = this.$el;
$('<span/>', {"class": 'ip'}).appendTo($el);
$el.append(' &nbsp; ', $('<input/>', {
"class": 'sel-all',
type: 'button',
val: 'Sel All'
}));
if (IDENT.auth == 'Admin')
$el.append($('<input/>', {
"class": 'ban',
type: 'button',
val: 'Ban'
}));
$el.append(
'<br>',
$('<input>', {"class": 'name', placeholder: 'Name'})
);
this.listenTo(this.model, 'change', this.render);
},
render: function () {
var attrs = this.model.attributes;
if (attrs.shallow) {
this.$('.ip').text(attrs.ip ? attrs.ip + ' "\u2026"' : 'Loading...');
return this;
}
this.$('.ip').text(attrs.ip);
var $name = this.$('.name');
if (!this.focusedName) {
_.defer(function () {
$name.focus().prop({
selectionStart: 0,
selectionEnd: $name.val().length,
});
});
this.focusedName = true;
}
if (attrs.name != $name.val()) {
$name.val(attrs.name);
}
this.$('.ban')
.val(attrs.ban ? 'Unban' : 'Ban');
return this;
},
entered_name: function (event) {
if (event.which != 13)
return;
event.preventDefault();
var name = this.$('.name').val().trim();
var ip = this.model.get('ip');
send([SET_ADDRESS_NAME, ip, name]);
this.remove();
},
remove: function () {
this.trigger('preremove');
Backbone.View.prototype.remove.call(this);
},
select_all: function () {
if (!THREAD)
return alert('TODO');
// TODO: do where query by ip_key lookup
var models = Threads.get(THREAD).get('replies').where({
ip: this.model.get('ip'),
});
if (!models.length)
return;
enable_multi_selecting();
with_dom(function () {
$.each(models, function () {
select_post($('#' + this.id));
});
});
this.remove();
},
ban: function () {
var ip = this.model.get('ip');
var attrs = this.model.attributes;
var act, type;
if (!attrs.ban) {
act = 'Ban';
type = 'timeout';
} else {
act = 'Unban';
type = 'unban';
}
if (!confirm(act + ' ' + ip + '?'))
return;
send([BAN, ip, type]);
// show ... while processing
this.$('.ban').val('...');
},
});
// basically just a link
var AddrView = Backbone.View.extend({
tagName: 'a',
className: 'mod addr',
events: {
click: 'toggle_expansion',
},
initialize: function () {
this.$el.attr('href', '#');
this.listenTo(this.model, 'change:name', this.render);
},
render: function () {
var attrs = this.model.attributes;
var text = ip_mnemonic(attrs.ip);
if (attrs.name)
text += ' "' + attrs.name + '"';
if (attrs.country)
text += ' ' + attrs.country;
this.$el.attr('title', attrs.ip).text(text);
return this;
},
toggle_expansion: function (event) {
if (event.target !== this.el)
return;
event.preventDefault();
if (this.expansion)
return this.expansion.remove();
var ip = this.model.get('ip');
if (!ip)
return;
this.expansion = new AddressView({model: this.model});
this.$el.after(this.expansion.render().el);
this.listenTo(this.expansion, 'preremove',
this.expansion_removed);
if (this.model.get('shallow'))
send([FETCH_ADDRESS, ip]);
},
remove: function () {
if (this.expansion)
this.expansion.remove();
Backbone.View.prototype.remove.call(this);
},
expansion_removed: function () {
this.expansion = null;
},
});
var Addresses = Backbone.Collection.extend({
model: Address,
comparator: function (a) { return ip_mnemonic(a.ip); },
});
window.addrs = new Addresses;
function hook_up_address(model, $post) {
var $a = $post.find('a.mod.addr:first');
if (!$a.length)
return;
var ip = $a.prop('title') || $a.text();
var givenName;
var m = $a.text().match(/^([\w'.:]+(?: [\w'.:]*)?) "(.+)"$/);
if (m) {
if (is_IPv4_ip(m[1]))
ip = m[1];
givenName = m[2];
}
if (!is_valid_ip(ip))
return;
/* Activate this address link */
var key = ip_key(ip);
var address = window.addrs.get(key);
if (!address) {<