. //////////////////////////////////////////////////////////////////////////////// // Last modified 24/oct/2017 by cassio@ime.usp.br require_once('db.php'); define("dbcompat_1_4_1", true); // sanitization function sanitizeVariables(&$item, $key) { if (!is_array($item)) { $item = sanitizeText($item); } } function myrawurlencode($txt) { return (rawurlencode(base64_encode($txt))); } function myrawurldecode($txt) { return (base64_decode(rawurldecode($txt))); } function filedownload($oid, $fname, $msg = '') { $uglysalt = "30a2224c82dcf42e497e2a1f6bd6516b"; $cf = globalconf(); $if = myrawurlencode(encryptData($fname, $uglysalt . $cf['key'], false)); $p = myhash($oid . $fname . $msg . $uglysalt . $cf["key"]); $str = "oid=" . $oid . "&filename=" . $if . "&check=" . $p; if ($msg != '') $str .= "&msg=" . myrawurlencode($msg); return $str; } function dirrec($dir, $user, $group, $dirPermissions, $filePermissions, $avoid = array()) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; if (is_dir($dir)) { $u = posix_getpwuid(fileowner($dir)); $un = $u['name']; $ug = $u['gid']; if ($un != $user) echo "user of $dir must be fixed!!\n"; if ($ug != $group) echo "group of $dir must be fixed!!\n"; if (@chmod($dir, $dirPermissions) === false) echo "cannot chmod $dir\n"; if (($dp = @opendir($dir)) === false) return; while ($file = readdir($dp)) { if (($file == ".") || ($file == "..")) continue; $cont = false; for ($i = 0; $i < count($avoid); $i++) if (substr($file, strlen($file) - strlen($avoid[$i])) == $avoid[$i]) { $cont = true; break; } if ($cont) continue; $fullPath = $dir . $ds . $file; dirrec($fullPath, $user, $group, $dirPermissions, $filePermissions, $avoid); } closedir($dp); } else { if (!is_link($dir)) { // $t = myunique(); //@copy($dir, $dir . '.tmp' . $t); //@rename($dir . '.tmp' . $t, $dir); $u = posix_getpwuid(fileowner($dir)); $un = $u['name']; $ug = $u['gid']; if ($un != $user) echo "user of $dir must be fixed!!\n"; if ($ug != $group) echo "group of $dir must be fixed!!\n"; if (@chmod($dir, $filePermissions) === false) echo "cannot chmod $dir\n"; } } } function fixbocadir($dir, $full = false) { if (is_dir($dir)) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; $u = posix_getpwuid(fileowner($dir)); $un = $u['name']; $ug = $u['gid']; @file_put_contents($dir . $ds . 'private' . $ds . '.htaccess', "Deny from all\n"); @touch($dir . $ds . 'private' . $ds . 'remotescores' . $ds . 'otherservers'); if ($full) $d = array('problemtmp', 'runtmp', 'scoretmp', 'remotescores', 'remotescoresfull', 'comp', 'logexternal', 'runslog'); else $d = array('problemtmp', 'runtmp', 'scoretmp'); foreach ($d as $a) cleardir($dir . $ds . 'private' . $ds . $a, true, true, false); dirrec($dir, $un, $ug, 0755, 0644, array('private', '.oldboca')); dirrec($dir . $ds . 'private', $un, $ug, 0750, 0640, array('.oldboca')); if (@file_put_contents($dir . $ds . 'private' . $ds . '.htaccess', "Deny from all\n") === false) return false; return true; } else { return false; } } function updatebocafile($dirboca, $dirz, $t) { $ok = 0; if (is_dir($dirz)) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; $d = @opendir($dirz); while (($file = @readdir($d)) !== false) { if ($file != '.' && $file != '..') $ok = $ok + updatebocafile($dirboca . $ds . $file, $dirz . $ds . $file, $t); } @closedir($d); @cleardir($dirz); } else { if (is_file($dirboca)) { copy($dirboca, $dirboca . '.' . $t . '.oldboca'); } else { file_put_contents($dirboca . '.' . $t . '.oldboca', ""); } @chmod($dirboca . '.' . $t . '.oldboca', 0000); if (rename($dirz, $dirboca) === true) $ok = 1; } return $ok; } function revertupdatebocafile($dirboca, $t) { $ok = 0; if (is_dir($dirboca)) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; $d = @opendir($dirboca); while (($file = @readdir($d)) !== false) { if ($file != '.' && $file != '..') $ok = $ok + revertupdatebocafile($dirboca . $ds . $file, $t); } @closedir($d); } else { if (is_file($dirboca) && substr($dirboca, strlen($dirboca) - strlen('.' . $t . '.oldboca')) == '.' . $t . '.oldboca') { @chmod($dirboca, 0600); if (@copy($dirboca, substr($dirboca, 0, strlen($dirboca) - strlen('.' . $t . '.oldboca'))) === true) $ok = 1; @chmod($dirboca, 0000); } } return $ok; } function cleardir($dir, $cddir = true, $secure = true, $removedir = true) { if (file_exists($dir)) { if (is_dir($dir)) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; if ($cddir) { @chdir($dir); @chdir('..'); } $d = @opendir($dir); while (($file = @readdir($d)) !== false) { if ($file != '.' && $file != '..') cleardir($dir . $ds . $file, false, $secure, true); } @closedir($d); if ($removedir) @rmdir($dir); } else { if ($secure && !is_link($dir) && is_file($dir)) file_put_contents($dir, str_repeat('XXXXXXXXXX', 10000)); @unlink($dir); } } } // gen random alphanum string function randstr($len = 8, $from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') { $str = ''; $fromlen = strlen($from); while ($len > 0) { $str .= substr($from, rand(0, $fromlen - 1), 1); $len--; } return $str; } function myhtmlspecialchars($text) { return sanitizeText($text, false); } // does the actual 'html' and 'sql' sanitization. function sanitizeText($text, $doamp = true) { if ($doamp) $text = str_replace("&", "&", $text); $text = str_replace("<", "<", $text); $text = str_replace(">", ">", $text); $text = str_replace("\"", """, $text); $text = str_replace("'", "'", $text); $text = str_replace("`", "`", $text); //$text = escape_string($text); $text = addslashes($text); return $text; } function sanitizeFilename($text) { $text = preg_replace('/[^[:print:]]/', '', $text); $text = str_replace(" ", "_", $text); $text = str_replace("*", "_", $text); $text = str_replace("$", "_", $text); $text = str_replace(")", "_", $text); $text = str_replace("(", "_", $text); $text = str_replace(";", "_", $text); $text = str_replace("&", "_", $text); $text = str_replace("<", "_", $text); $text = str_replace(">", "_", $text); $text = str_replace("\"", "_", $text); $text = str_replace("'", "_", $text); $text = str_replace("`", "_", $text); $text = addslashes($text); return $text; } function unsanitizeText($text) { $text = str_replace("<", "<", $text); $text = str_replace(">", ">", $text); $text = str_replace("&", "&", $text); return $text; } array_walk_recursive($_FILES, 'sanitizeVariables'); array_walk_recursive($_POST, 'sanitizeVariables'); array_walk_recursive($_GET, 'sanitizeVariables'); array_walk_recursive($_COOKIE, 'sanitizeVariables'); //name of calling function function getFunctionName($num = 2) { if (strcmp(phpversion(), '5.3.6') < 0) { $backtrace = debug_backtrace(); } else { if (strcmp(phpversion(), '5.4.0') < 0) $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); else $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, $num + 5); } $ret = ''; for ($i = 0; $i < $num; $i++) if (isset($backtrace[$i]) && isset($backtrace[$i]['function'])) $ret .= " " . $backtrace[$i]['function']; if ($ret == '') $ret = 'undef'; return $ret; } function getIP() { if (getenv("REMOTE_ADDR")) { if (getenv("BOCA_TRUSTED_PROXIES")) $proxies = explode(",", getenv("BOCA_TRUSTED_PROXIES")); if ($proxies && in_array(getenv("REMOTE_ADDR"), $proxies) && getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR"); } else return "UNKNOWN"; if (defined("dbcompat_1_4_1") && dbcompat_1_4_1 == true) return $ip; $ip1 = ''; if (getenv("HTTP_X_FORWARDED_FOR")) { $ip1 = getenv("HTTP_X_FORWARDED_FOR"); $ip1 = strtok($ip1, ","); if ($ip1 != $ip) $ip .= ';' . $ip1; } if (getenv("HTTP_X_CLIENTIP")) { $ip1a = getenv("HTTP_X_CLIENTIP"); $ip1a = strtok($ip1a, ","); if ($ip1a != $ip1 && $ip1a != getenv("REMOTE_ADDR")) $ip .= ';' . $ip1a; } if (getenv("HTTP_CLIENT_IP")) { $ip2 = getenv("HTTP_CLIENT_IP"); $ip2 = strtok($ip2, ","); if ($ip2 != $ip1a && $ip1 != $ip2 && $ip2 != getenv("REMOTE_ADDR")) $ip .= ';' . $ip2; } else { if (getenv('HTTP_X_FORWARDED')) { $ip .= ';' . getenv('HTTP_X_FORWARDED'); } else { if (getenv('HTTP_FORWARDED')) { $ip .= ';' . getenv('HTTP_FORWARDED'); } } } return sanitizeText($ip); } //retorna ip e hostname do cliente function getIPHost() { $ips = explode(';', getIP()); $s = ''; for ($ipn = 0; $ipn < count($ips); $ipn++) { $ip = $ips[$ipn]; //next lines where suggested to be removed by //Mario Sanchez (Ing. de Sistemas y Computacion, Universidad de los Andes, Bogota, Colombia) //because they are very slow to run depending on the network // $host = @gethostbyaddr($ip); // if ($host != $ip && $host != "") // $s .= $ip . "(" . $host . ") "; // else $s .= $ip . ' '; } return $s; } //trata o caso de sessao invalida function InvalidSession($where) { $msg = "Session expired on $where"; LOGLevel($msg, 3); unset($_SESSION["usertable"]); MSGError("Session expired. You must log in again."); } //trata o caso de tentativa de burlar as regras function IntrusionNotify($where) { $msg = "Security Violation: $where"; if (isset($_SESSION["usertable"]["username"])) $msg .= " (" . $_SESSION["usertable"]["username"] . "/" . $_SESSION["usertable"]["usersitenumber"] . ")"; unset($_SESSION["usertable"]); LOGLevel($msg, 1); MSGError("Violation ($where). Admin warned."); } function ValidCookie($dolog = false, $gip = '') { if (!isset($_SESSION["usertable"])) return (FALSE); $contest = $_SESSION["usertable"]["contestnumber"]; $name = $_SESSION["usertable"]["username"]; $coo = array(); if (isset($_COOKIE['biscoitobocabombonera'])) { $coo = explode('-', $_COOKIE['biscoitobocabombonera']); if ( count($coo) != 2 || strlen($coo[1]) != strlen(myhash('xxx')) || !is_numeric($coo[0]) || !ctype_alnum($coo[1]) ) $coo = array(); } $_SESSION['onlycmd'] = 1; $_SESSION['prevco'] = 'none'; if (count($coo) == 2) { $ds = DIRECTORY_SEPARATOR; if ($ds == "") $ds = "/"; $dircode = $_SESSION["locr"] . $ds . "private" . $ds . "cookies"; @mkdir($dircode); $dircode .= $ds . $contest . '-' . $name; if (@file_exists($dircode)) { if (($prevuser = @file_get_contents($dircode)) === false) { if ($dolog) { @file_put_contents($dircode . '.log', time() . '|' . $prevuser . '|' . $coo[0] . '|' . $coo[1] . '|' . $gip . "|file\n", FILE_APPEND | LOCK_EX); LOGLevel("User $name contest $contest has a cookie file problem.", 2); } return false; } $_SESSION['prevco'] = $prevuser; $tt = time(); if ($prevuser != $coo[1]) { if ($dolog) { $ans = 'new'; if ($coo[0] < $tt - 15) $ans = 'invalid'; @file_put_contents($dircode . '.log', time() . '|' . $prevuser . '|' . $coo[0] . '|' . $coo[1] . '|' . $gip . "|" . $ans . "\n", FILE_APPEND | LOCK_EX); LOGLevel("User $name contest $contest has $ans cookie.", 2); } if ($_SESSION["usertable"]["usertype"] == 'team') { if ($coo[0] < $tt - 15) return false; } else @file_put_contents($dircode, $coo[1]); } else $_SESSION['onlycmd'] = 0; } else { $_SESSION['onlycmd'] = 0; @file_put_contents($dircode, $coo[1]); } } else { LOGLevel("User $name contest $contest has bad cookie.", 2); return false; } return true; } // verifica se a sessao esta aberta e ok function ValidSession() { if (!isset($_SESSION["usertable"])) return (FALSE); if ($_SESSION["usertable"]["usersession"] != session_id()) return (FALSE); $gip = getIP(); //if(!ValidCookie()) return false; // cassiopc: sites that use multiple IP addresses to go out create a serious problem to check IPs... // if(substr($_SESSION["usertable"]["userip"],0,6) != '157.92') { // if ($_SESSION["usertable"]["userip"] != $gip || // $_SESSION["usertable"]["usersession"] != session_id()) return(FALSE); // } else { // if($_SESSION["usertable"]["usersession"] != session_id()) return(FALSE); // } $tmp = DBUserInfo( $_SESSION["usertable"]["contestnumber"], $_SESSION["usertable"]["usersitenumber"], $_SESSION["usertable"]["usernumber"] ); if ($tmp['usersession'] == '') return (FALSE); if ($_SESSION["usertable"]["usermultilogin"] == 't') return (TRUE); if ($tmp["userip"] != $gip) { @file_put_contents("/tmp/bocalogin.log", $tmp["userip"] . "|" . $gip . '|' . $_SESSION["usertable"]["usersession"] . '|' . $_SESSION["usertable"]["usernumber"] . '|' . date(DATE_RFC2822) . "\n", LOCK_EX | FILE_APPEND); // return(FALSE); //cassiopc: they may create a problem here too... } return (TRUE); } // grava erro no arquivo de log function LOGError($msg) { LOGLevel($msg, 0, false); } function LOGInfo($msg) { LOGLevel($msg, 2, false); } // grava linha no arquivo de log com o nivel especificado function LOGLevel($msg, $level, $dodb = true) { $msga = sanitizeText(str_replace("\n", " ", $msg)); $msg = now() . ": "; // if php version arrives to 5.10 then this will not work!! if (strcmp(phpversion(), '5.4.0') < 0) define_syslog_variables(); $prior = LOG_CRIT; switch ($level) { case 0: $msg .= "ERROR: "; $type = "error"; $prior = LOG_ERR; break; case 1: $msg .= "WARN: "; $type = "warn"; $prior = LOG_WARNING; break; case 2: $msg .= "INFO: "; $type = "info"; $prior = LOG_INFO; break; case 3: $msg .= "DEBUG: "; $type = "debug"; $prior = LOG_DEBUG; break; } $msg .= getIPHost() . ": " . $msga; openlog("BOCA", LOG_ODELAY, LOG_USER); syslog($prior, $msg); closelog(); if ($dodb && isset($_SESSION["usertable"])) DBNewLog( $_SESSION["usertable"]["contestnumber"], $_SESSION["usertable"]["usersitenumber"], $_SESSION["usertable"]["usernumber"], $type, getIP(), $msga, "" ); } function mytime() { return time(); } function mymtime() { return microtime(true); } function myunique($val = 0) { return (((int) (100 * microtime(true))) % 10000000) * 100 + ($val % 100); } //retorna data e hora atuais function now() { return date('H\:i:s T \- d/M/Y'); } //retorna data e hora em seg convertida para padrao function dateconv($d) { return date('H\:i:s T \- d/M/Y', $d); } //retorna data e hora em seg convertida para padrao simples function dateconvsimple($d) { return date('H\:i', $d); } //transforma segundos para minutos function dateconvminutes($d) { return (int) ($d / 60); } //alerta mensagem via javascript function MSGError($msg) { $msg = str_replace("\n", " ", $msg); echo "\n"; } //gera script para voltar aa tela dada function ForceLoad($where) { echo "\n"; exit; } function ForceClose() { echo "\n"; exit; } /** * Compare an IP address to network(s) * * The network(s) argument may be a string or an array. A negative network * match must start with a "!". Depending on the 3rd parameter, it will * return true or false on the first match, or any negative rule will have * absolute priority (default). * * Samples: * match_network ("192.168.1.0/24", "192.168.1.1") -> true * * match_network (array ("192.168.1.0/24", "!192.168.1.1"), "192.168.1.1") -> false * match_network (array ("192.168.1.0/24", "!192.168.1.1"), "192.168.1.1", true) -> true * match_network (array ("!192.168.1.0/24", "192.168.1.1"), "192.168.1.1") -> false * match_network (array ("!192.168.1.0/24", "192.168.1.1"), "192.168.1.1", true) -> false * * @param mixed Network to match * @param string IP address * @param bool true: first match will return / false: priority to negative rules (default) * @see http://php.benscom.com/manual/en/function.ip2long.php#56373 */ function match_network($nets, $ip) { if (!is_array($nets)) $nets = explode(",", $nets); foreach ($nets as $net) { $net = trim($net); $rev = (preg_match("/^\!/", $net)) ? true : false; $net = preg_replace("/^\!/", "", $net); $ip_arr = explode('/', $net); $net_long = ip2long(trim($ip_arr[0])); if (count($ip_arr) > 1 && trim($ip_arr[1]) != '') { $x = ip2long(trim($ip_arr[1])); $mask = long2ip($x) == ((int) trim($ip_arr[1])) ? $x : 0xffffffff << (32 - ((int) trim($ip_arr[1]))); } else { $mask = 0xffffffff; } $ip_long = ip2long($ip); if ($rev) { if (($ip_long & $mask) != ($net_long & $mask)) return true; } else { if (($ip_long & $mask) == ($net_long & $mask)) return true; } } return false; } // eof ?>