328 lines
14 KiB
PHP
328 lines
14 KiB
PHP
<?php
|
||
require_once(dirname(__FILE__)."/db_info.inc.php");
|
||
require_once(dirname(__FILE__)."/curl.php");
|
||
require_once(dirname(__FILE__)."/const.inc.php");
|
||
function has_bad_words($words){
|
||
global $bad_words;
|
||
foreach($bad_words as $bad){
|
||
if(stristr($words,$bad) === FALSE){
|
||
continue;
|
||
}else{
|
||
// echo $bad;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
function starred($user_id){
|
||
$stars=pdo_query("select starred from users where user_id=?",$user_id);
|
||
if(!empty($stars)&& $stars[0][0]>0 ) return true;
|
||
$stars=json_decode(curl_get("https://api.github.com/users/$user_id/starred?per_page=100"));
|
||
foreach( $stars as $star){
|
||
if($star->full_name=="zhblue/hustoj"){
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
function create_subdomain($user_id,$template="bs3",$friendly="0"){
|
||
$user_id=strtolower($user_id);
|
||
global $DB_NAME,$DB_USER,$DB_PASS,$DOMAIN;
|
||
$NEW_USER="hustoj_".$user_id;
|
||
$NEW_PASS=substr(pwGen($user_id),10);
|
||
$FARMBASE="/home/saas";
|
||
$templates=array("bs3","mdui","bshark","sweet","syzoj","sidebar");
|
||
if(!in_array($template,$templates)) $template="bs3";
|
||
pdo_query("create database `jol_$user_id`;\n");
|
||
pdo_query("drop USER '$NEW_USER'@'localhost';");
|
||
pdo_query("create USER '$NEW_USER'@'localhost' identified by '$NEW_PASS';");
|
||
pdo_query("grant all privileges on `jol\\_".str_replace("_","\\_",$user_id)."`.* to '$NEW_USER'@'localhost' ;");
|
||
pdo_query("flush privileges;\n");
|
||
$sql="use `jol_$user_id`;\n";
|
||
$csql=file_get_contents("/home/judge/src/install/db.sql");
|
||
$sql.=mb_substr($csql,64);
|
||
pdo_query($sql);
|
||
$CONF_STR="<?php \$OJ_NAME='$user_id';\n";
|
||
$CONF_STR.="\$DB_HOST='localhost';\n"; //数据库服务器ip或域名
|
||
$CONF_STR.="\$DB_NAME='jol_$user_id';\n"; //数据库名
|
||
$CONF_STR.="\$DB_USER='$NEW_USER';\n"; //数据库名
|
||
$CONF_STR.="\$DB_PASS='$NEW_PASS';\n"; //数据库名
|
||
$CONF_STR.="\$OJ_DATA='$FARMBASE/$user_id/data';\n"; //:测试数据目录
|
||
$CONF_STR.="\$OJ_JUDGE_HUB_PATH='$user_id';\n"; //:OJ在farmpath中的子目录名
|
||
$CONF_STR.="\$OJ_LANGMASK=2097084;\n"; //:语言类型
|
||
$CONF_STR.="\$OJ_TEMPLATE='$template';\n"; //:模板名
|
||
$CONF_STR.="\$OJ_REG_NEED_CONFIRM=false;\n"; //:允许注册
|
||
$CONF_STR.="\$OJ_FRIENDLY_LEVEL=$friendly;\n"; //友善级别
|
||
|
||
$CONF_FILE=realpath(dirname(__FILE__)."/../")."/SaaS/$user_id.".$DOMAIN.".php";
|
||
//if ($user_id=="zhblue") echo "<textarea>".$sql."</textarea>";
|
||
// echo "<pre>".htmlentities($CONF_STR);
|
||
// echo "</pre>".$CONF_FILE;
|
||
mkdir($FARMBASE."/$user_id/run0",0755,true);
|
||
mkdir($FARMBASE."/$user_id/data",0700,true);
|
||
mkdir($FARMBASE."/$user_id/etc",0700,true);
|
||
mkdir($FARMBASE."/$user_id/log",0700,true);
|
||
mkdir(dirname($CONF_FILE),0700,true);
|
||
file_put_contents($CONF_FILE,$CONF_STR);
|
||
$CONF_STR="OJ_HOST_NAME=127.0.0.1\n";
|
||
$CONF_STR.="OJ_DB_NAME=jol_".$user_id."\n";
|
||
$CONF_STR.="OJ_USER_NAME=".$NEW_USER."\n";
|
||
$CONF_STR.="OJ_PASSWORD=".$NEW_PASS."\n";
|
||
$CONF_STR.="OJ_USE_DOCKER=1\n";
|
||
$CONF_STR.="OJ_HTTP_USERNAME=CF-T8\n";
|
||
$CONF_STR.="OJ_LANG_SET=0,1,6\n";
|
||
$CONF_STR.="OJ_OI_MODE=1\n";
|
||
|
||
|
||
$CONF_FILE=$FARMBASE."/".$user_id."/etc/judge.conf";
|
||
// echo "<pre>".htmlentities($CONF_STR);
|
||
// echo "</pre>".$CONF_FILE;
|
||
file_put_contents($CONF_FILE,$CONF_STR);
|
||
|
||
$CONF_STR='
|
||
grant {
|
||
permission java.io.FilePermission "./-", "read,write";
|
||
permission java.io.FilePermission "/usr/lib/jvm", "read";
|
||
};
|
||
';
|
||
|
||
$CONF_FILE=$FARMBASE."/".$user_id."/etc/java0.policy";
|
||
// echo "<pre>".htmlentities($CONF_STR);
|
||
// echo "</pre>".$CONF_FILE;
|
||
file_put_contents($CONF_FILE,$CONF_STR);
|
||
$DB_NAME="jol_".$user_id;
|
||
$sql="delete from jol_".$user_id.".privilege where user_id='".$user_id."'; ";
|
||
pdo_query($sql);
|
||
$sql="INSERT INTO jol_".$user_id.".privilege(user_id,rightstr,valuestr,defunct) values('".$user_id."', 'administrator', 'true', 'N');";
|
||
pdo_query($sql);
|
||
$sql="INSERT INTO jol_".$user_id.".privilege(user_id,rightstr,valuestr,defunct) values('".$user_id."', 'source_browser', 'true', 'N');";
|
||
pdo_query($sql);
|
||
|
||
}
|
||
function mb_trim($string, $trim_chars = '\s'){
|
||
return preg_replace('/^['.$trim_chars.']*(?U)(.*)['.$trim_chars.']*$/u', '\\1',$string);
|
||
}
|
||
function send_udp_message($host, $port, $message)
|
||
{
|
||
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||
@socket_connect($socket, $host, $port);
|
||
|
||
$num = 0;
|
||
$length = strlen($message);
|
||
do
|
||
{
|
||
$buffer = substr($message, $num);
|
||
$ret = @socket_write($socket, $buffer);
|
||
$num += $ret;
|
||
} while ($num < $length);
|
||
|
||
socket_close($socket);
|
||
|
||
// UDP ............, ............
|
||
return true;
|
||
}
|
||
function trigger_judge($solution_id=0){
|
||
global $OJ_UDPSERVER,$OJ_UDPPORT,$OJ_JUDGE_HUB_PATH;
|
||
$JUDGE_SERVERS = explode(",",$OJ_UDPSERVER);
|
||
$JUDGE_TOTAL = count($JUDGE_SERVERS);
|
||
|
||
$select = $solution_id%$JUDGE_TOTAL;
|
||
$JUDGE_HOST = $JUDGE_SERVERS[$select];
|
||
|
||
if (strstr($JUDGE_HOST,":")!==false) {
|
||
$JUDGE_SERVERS = explode(":",$JUDGE_HOST);
|
||
$JUDGE_HOST = $JUDGE_SERVERS[0];
|
||
$OJ_UDPPORT = $JUDGE_SERVERS[1];
|
||
}
|
||
if(isset($OJ_JUDGE_HUB_PATH))
|
||
send_udp_message($JUDGE_HOST, $OJ_UDPPORT, $OJ_JUDGE_HUB_PATH);
|
||
else
|
||
send_udp_message($JUDGE_HOST, $OJ_UDPPORT, $solution_id );
|
||
}
|
||
function crypto_rand_secure($min, $max) {
|
||
$range = $max - $min;
|
||
if ($range < 0) return $min; // not so random...
|
||
$log = log($range, 2);
|
||
$bytes = (int) ($log / 8) + 1; // length in bytes
|
||
$bits = (int) $log + 1; // length in bits
|
||
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
|
||
do {
|
||
if(function_exists("openssl_random_pseudo_bytes")){
|
||
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
|
||
}else{
|
||
$rnd = hexdec(bin2hex(rand()."_".rand()));
|
||
}
|
||
$rnd = $rnd & $filter; // discard irrelevant bits
|
||
} while ($rnd >= $range);
|
||
return $min + $rnd;
|
||
}
|
||
|
||
function getToken($length=32){
|
||
$token = "";
|
||
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
|
||
$codeAlphabet.= "0123456789";
|
||
for($i=0;$i<$length;$i++){
|
||
$token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
|
||
}
|
||
return $token;
|
||
}
|
||
|
||
function pwGen($password,$md5ed=False)
|
||
{
|
||
if (!$md5ed) $password=md5($password);
|
||
$salt = sha1(rand());
|
||
$salt = substr($salt, 0, 4);
|
||
$hash = base64_encode( sha1($password . $salt, true) . $salt );
|
||
return $hash;
|
||
}
|
||
|
||
function pwCheck($password,$saved)
|
||
{
|
||
if (isOldPW($saved)){
|
||
if(!isOldPW($password)) $mpw = md5($password);
|
||
else $mpw=$password;
|
||
if ($mpw==$saved) return True;
|
||
else return False;
|
||
}
|
||
$svd=base64_decode($saved);
|
||
$salt=substr($svd,20);
|
||
if(!isOldPW($password)) $password=md5($password);
|
||
$hash = base64_encode( sha1(($password) . $salt, true) . $salt );
|
||
if (strcmp($hash,$saved)==0) return True;
|
||
else return False;
|
||
}
|
||
|
||
function isOldPW($password)
|
||
{
|
||
if(strlen($password)!=32) return false;
|
||
for ($i=strlen($password)-1;$i>=0;$i--)
|
||
{
|
||
$c = $password[$i];
|
||
if ('0'<=$c && $c<='9') continue;
|
||
if ('a'<=$c && $c<='f') continue;
|
||
if ('A'<=$c && $c<='F') continue;
|
||
return False;
|
||
}
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
如果希望允许用户名是中文,可以替换下面的is_valid_user_name函数为这个版本
|
||
|
||
function is_valid_user_name($user_name){
|
||
$res = preg_match('/^[\x{4e00}-\x{9fa5}A-Za-z0-9 _::,,.。…\/、~`@#¥%&×+|{}=-*^$~!@#$%^&*()\+-—=()!¥{}【】\[\]\|;;《》<>\?\?\·]+$/u', $user_name);
|
||
return $res ? TRUE : FALSE;
|
||
|
||
}
|
||
*/
|
||
function is_valid_user_name($user_name){
|
||
$len=strlen($user_name);
|
||
for ($i=0;$i<$len;$i++){
|
||
if (
|
||
($user_name[$i]>='a' && $user_name[$i]<='z') ||
|
||
($user_name[$i]>='A' && $user_name[$i]<='Z') ||
|
||
($user_name[$i]>='0' && $user_name[$i]<='9') ||
|
||
$user_name[$i]=='-'||
|
||
$user_name[$i]=='_'||
|
||
($i==0 && $user_name[$i]=='*')
|
||
);
|
||
else return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function sec2str($sec){
|
||
return sprintf("%02d:%02d:%02d",$sec/3600,$sec%3600/60,$sec%60);
|
||
}
|
||
function is_running($cid){
|
||
$now=date('Y-m-d H:i', time());
|
||
$sql="SELECT count(*) FROM `contest` WHERE `contest_id`=? AND `end_time`>?";
|
||
$result=pdo_query($sql,$cid,$now);
|
||
$row=$result[0];
|
||
$cnt=intval($row[0]);
|
||
return $cnt>0;
|
||
}
|
||
function check_ac($cid,$pid,$noip){
|
||
//require_once("./include/db_info.inc.php");
|
||
global $OJ_NAME;
|
||
if($noip){
|
||
$sql="SELECT count(*) FROM `solution` WHERE `contest_id`=? AND `num`=? and `problem_id`!=0 AND `user_id`=?";
|
||
$result=pdo_query($sql,$cid,$pid,$_SESSION[$OJ_NAME.'_'.'user_id']);
|
||
$row=$result[0];
|
||
$sub=intval($row[0]);
|
||
if ($sub>0) return "<div class='label label-default'>?</div>";
|
||
else return "";
|
||
|
||
}
|
||
$sql="SELECT count(*) FROM `solution` WHERE `contest_id`=? AND `num`=? AND `result`='4' AND `user_id`=?";
|
||
$result=pdo_query($sql,$cid,$pid,$_SESSION[$OJ_NAME.'_'.'user_id']);
|
||
$row=$result[0];
|
||
$ac=intval($row[0]);
|
||
if ($ac>0) return "<div class='label label-success'>Y</div>";
|
||
|
||
$sql="SELECT count(*) FROM `solution` WHERE `contest_id`=? AND `num`=? AND `result`!=4 and `problem_id`!=0 AND `user_id`=?";
|
||
$result=pdo_query($sql,$cid,$pid,$_SESSION[$OJ_NAME.'_'.'user_id']);
|
||
$row=$result[0];
|
||
$sub=intval($row[0]);
|
||
|
||
if ($sub>0) return "<div class='label label-danger'>N</div>";
|
||
else return "";
|
||
}
|
||
|
||
|
||
|
||
function RemoveXSS($val) {
|
||
// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
|
||
// this prevents some character re-spacing such as <java\0script>
|
||
// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
|
||
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
|
||
|
||
// straight replacements, the user should never need these since they're normal characters
|
||
// this prevents like <IMG SRC=@avascript:alert('XSS')>
|
||
$search = 'abcdefghijklmnopqrstuvwxyz';
|
||
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||
$search .= '1234567890!@#$%^&*()';
|
||
$search .= '~`";:?+/={}[]-_|\'\\';
|
||
for ($i = 0; $i < strlen($search); $i++) {
|
||
// ;? matches the ;, which is optional
|
||
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
|
||
|
||
// @ @ search for the hex values
|
||
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
|
||
// @ @ 0{0,7} matches '0' zero to seven times
|
||
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
|
||
}
|
||
|
||
// now the only remaining whitespace attacks are \t, \n, and \r //, 'style'
|
||
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'frameset', 'ilayer', 'bgsound');
|
||
$ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
|
||
$ra = array_merge($ra1, $ra2);
|
||
|
||
$found = true; // keep replacing as long as the previous round replaced something
|
||
while ($found == true) {
|
||
$val_before = $val;
|
||
for ($i = 0; $i < sizeof($ra); $i++) {
|
||
$pattern = '/';
|
||
for ($j = 0; $j < strlen($ra[$i]); $j++) {
|
||
if ($j > 0) {
|
||
$pattern .= '(';
|
||
$pattern .= '(&#[xX]0{0,8}([9ab]);)';
|
||
$pattern .= '|';
|
||
$pattern .= '|(�{0,8}([9|10|13]);)';
|
||
$pattern .= ')*';
|
||
}
|
||
$pattern .= $ra[$i][$j];
|
||
}
|
||
$pattern .= '/i';
|
||
$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag
|
||
$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
|
||
if ($val_before == $val) {
|
||
// no replacements were made, so exit the loop
|
||
$found = false;
|
||
}
|
||
}
|
||
}
|
||
return $val;
|
||
}
|