$forbidden)); return; } //check all elements for a valid hash $hash = false; foreach($u as $el) { if(isExistingHash($el)) { $hash = $el; break; } // if we don't have a hash yet but the element looks like it could be a hash if($hash === false && mightBeAHash($el)) { if(!$sc) $sc = getStorageControllers(); foreach($sc as $contr) { $c = new $contr(); if($c->isEnabled()===true && $c->hashExists($el)) { $hash = $el; $c->pullFile($hash,ROOT.DS.'tmp'.DS.$hash); if(!file_exists(ROOT.DS.'tmp'.DS.$hash)) continue; storeFile(ROOT.DS.'tmp'.DS.$hash,$hash,true); break; // we break here because we already have the file. no need to check other storage controllers } else if($c->isEnabled()===true && defined('ENCRYPTION_KEY') && ENCRYPTION_KEY !='' && $c->hashExists($el.'.enc')) //this is an encrypted file. Let's decrypt it { $hash = $el.'.enc'; $c->pullFile($hash,ROOT.DS.'tmp'.DS.$hash); if(!file_exists(ROOT.DS.'tmp'.DS.$hash)) continue; $enc = new Encryption; $hash = substr($hash,0,-4); $enc->decryptFile(ROOT.DS.'tmp'.DS.$el.'.enc', ROOT.DS.'tmp'.DS.$hash,base64_decode(ENCRYPTION_KEY)); storeFile(ROOT.DS.'tmp'.DS.$hash,$hash,true); unlink(ROOT.DS.'tmp'.DS.$el.'.enc'); break; // we break here because we already have the file. no need to check other storage controllers } } } // if it's still false, we only have one hope: Maybe it's from a dynamic controller and the cache hasn't been created yet else if($hash===false) { foreach(loadAllContentControllers(true) as $cc) { if((new $cc)::ctype=='dynamic' && in_array((new $cc)->getRegisteredExtensions()[0],$u) ) { $hash = true; break; } } } } //we didn't find a hash. send error 404 if($hash===false) { http_response_code(404); die("404"); } else { //ok we have a valid hash. //is the user requesting this file to be deleted? foreach($u as $el) { if(startsWith($el,'delete_')) { $code = substr($el,7); //@todo: allow MASTER_DELETE_IP to be CIDR range or coma separated if(getDeleteCodeOfHash($hash)==$code || (defined('MASTER_DELETE_CODE') && MASTER_DELETE_CODE==$code ) || (defined('MASTER_DELETE_IP') && MASTER_DELETE_IP==getUserIP()) ) { deleteHash($hash); exit($hash.' deleted successfully'); } } } //Now let's check the extension to find out which controller will be handling this request $extension = pathinfo($hash, PATHINFO_EXTENSION); foreach(loadAllContentControllers(true) as $cc) { if( ((new $cc)::ctype=='dynamic' && in_array((new $cc)->getRegisteredExtensions()[0],$u)) || ((new $cc)::ctype=='static' && in_array($extension,(new $cc)->getRegisteredExtensions())) ) { (new $cc())->handleHash($hash,$u); return; } } http_response_code(404); die("404"); } //var_dump($u); } function storageControllerUpload($hash) { // Lets' check all storage controllers and tell them that a new file was uploaded $sc = getStorageControllers(); $allgood = true; $uploadedhash =$hash; foreach($sc as $contr) { $controller = new $contr(); if($controller->isEnabled()===true) { $source = getDataDir().DS.$hash.DS.$hash; if(defined('ENCRYPTION_KEY') && ENCRYPTION_KEY) //ok so we got an encryption key which means we'll store only the encrypted file { $enc = new Encryption; $encoded_file = ROOT.DS.'tmp'.DS.$hash.'.enc'; $enc->encryptFile($source,$encoded_file,base64_decode(ENCRYPTION_KEY)); $controller->pushFile($encoded_file,$hash.'.enc'); unlink($encoded_file); $uploadedhash = $hash.'.enc'; } else // not encrypted $controller->pushFile($source,$hash); //let's check if the file is really there. If not, queue it for later if(!$controller->hashExists($uploadedhash)) { $allgood = false; $queuefile=ROOT.DS.'tmp'.DS.'controllerqueue.txt'; if(!file_exists($queuefile) || !stringInFile($hash,$queuefile)) { $fp=fopen($queuefile,'a'); if($fp) { fwrite($fp,$hash."\n"); fclose($fp); } } } } } return $allgood; } function stringInFile($string,$file) { $handle = fopen($file, 'r'); while (($line = fgets($handle)) !== false) { $line=trim($line); if($line==$string) return true; } fclose($handle); return false; } function getNewHash($type,$length=10) { while(1) { $hash = getRandomString($length).'.'.$type; if(!isExistingHash($hash)) return $hash; $length++; } } function isExistingHash($hash) { if(!trim($hash)) return false; return is_dir(getDataDir().DS.$hash); } function mightBeAHash($string) { $len = strlen($string); $dot = strpos($string,'.'); if(substr_count($string,'.')!=1) return false; if(!$dot) return false; $afterdot = substr($string,$dot+1); //@todo: maybe pull all allowed types and compare to afterdot return ($afterdot && strlen($afterdot)>=2 && strlen($afterdot)<=5 ); } function autoload($className) { if (file_exists(ROOT . DS . 'interfaces' . DS . strtolower($className) . '.interface.php')) require_once(ROOT . DS . 'interfaces' . DS . strtolower($className) . '.interface.php'); if ($className=='Encryption') require_once(ROOT . DS . 'inc' . DS . 'encryption.php'); } function renderTemplate($template,$vars=false) { if(is_array($vars)) extract($vars); include_once(ROOT.DS.'templates'.DS.$template.'.html'); } function getExtensionOfFilename($file) { return pathinfo($file, PATHINFO_EXTENSION); } function sizeStringToWidthHeight($size) { if(!$size || !isSize($size)) return false; if(!is_numeric($size)) $size = explode('x',$size); if(is_array($size)) { $maxwidth = $size[0]; $maxheight = $size[1]; } else if($size) { $maxwidth = $size; $maxheight = $size; } return array('width'=>$maxwidth,'height'=>$maxheight); } // // from: https://stackoverflow.com/questions/25975943/php-serve-mp4-chrome-provisional-headers-are-shown-request-is-not-finished-ye // function serveFile($filename, $filename_output = false, $mime = 'application/octet-stream') { $buffer_size = 8192; $expiry = 90; //days if(!file_exists($filename)) { throw new Exception('File not found: ' . $filename); } if(!is_readable($filename)) { throw new Exception('File not readable: ' . $filename); } header_remove('Cache-Control'); header_remove('Pragma'); $byte_offset = 0; $filesize_bytes = $filesize_original = filesize($filename); header('Accept-Ranges: bytes', true); header('Content-Type: ' . $mime, true); header("Content-Disposition: inline;"); // Content-Range header for byte offsets if (isset($_SERVER['HTTP_RANGE']) && preg_match('%bytes=(\d+)-(\d+)?%i', $_SERVER['HTTP_RANGE'], $match)) { $byte_offset = (int) $match[1];//Offset signifies where we should begin to read the file if (isset($match[2]))//Length is for how long we should read the file according to the browser, and can never go beyond the file size { $filesize_bytes = min((int) $match[2], $filesize_bytes - $byte_offset); } header("HTTP/1.1 206 Partial content"); header(sprintf('Content-Range: bytes %d-%d/%d', $byte_offset, $filesize_bytes - 1, $filesize_original)); ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent } $byte_range = $filesize_bytes - $byte_offset; header('Content-Length: ' . $byte_range); header('Expires: ' . date('D, d M Y H:i:s', time() + 60 * 60 * 24 * $expiry) . ' GMT'); $buffer = ''; $bytes_remaining = $byte_range; $handle = fopen($filename, 'r'); if(!$handle) { throw new Exception("Could not get handle for file: " . $filename); } if (fseek($handle, $byte_offset, SEEK_SET) == -1) { throw new Exception("Could not seek to byte offset %d", $byte_offset); } while ($bytes_remaining > 0) { $chunksize_requested = min($buffer_size, $bytes_remaining); $buffer = fread($handle, $chunksize_requested); $chunksize_real = strlen($buffer); if ($chunksize_real == 0) { break; } $bytes_remaining -= $chunksize_real; echo $buffer; flush(); } } function sanatizeString($string) { return preg_replace("/[^a-zA-Z0-9._\-]+/", "", $string); } function renderSize($byte) { if($byte < 1024) { $result = round($byte, 2). ' Byte'; }elseif($byte < pow(1024, 2)) { $result = round($byte/1024, 2).' KB'; }elseif($byte >= pow(1024, 2) and $byte < pow(1024, 3)) { $result = round($byte/pow(1024, 2), 2).' MB'; }elseif($byte >= pow(1024, 3) and $byte < pow(1024, 4)) { $result = round($byte/pow(1024, 3), 2).' GB'; }elseif($byte >= pow(1024, 4) and $byte < pow(1024, 5)) { $result = round($byte/pow(1024, 4), 2).' TB'; }elseif($byte >= pow(1024, 5) and $byte < pow(1024, 6)) { $result = round($byte/pow(1024, 5), 2).' PB'; }elseif($byte >= pow(1024, 6) and $byte < pow(1024, 7)) { $result = round($byte/pow(1024, 6), 2).' EB'; } return $result; } function getTypeOfFile($url) { // on linux use the "file" command or it will handle everything as octet-stream if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { $content_type = exec("file -bi " . escapeshellarg($url)); if($content_type && strpos($content_type,'/')!==false && strpos($content_type,';')!==false) $type = $content_type; } else { //for windows we'll use mime_content_type. Make sure you have enabled the "exif" extension in php.ini $type = mime_content_type($url); } if(!$type) return false; if(startsWith($type,'text')) return 'text'; $arr = explode(';', trim($type)); if(count($arr)>1) { $a2 = explode('/', $arr[0]); $type = $a2[1]; } else { $a2 = explode('/', $type); $type = $a2[1]; } if($type=='octet-stream') if((new VideoController())->isProperMP4($url)) return 'mp4'; if($type=='mp4') if(!(new VideoController())->isProperMP4($url)) return false; return $type; } function isFolderWritable($dir){return is_writable($dir);} function getRandomString($length=32, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyz') { $str = ''; $max = mb_strlen($keyspace, '8bit') - 1; for ($i = 0; $i < $length; ++$i) { $str .= $keyspace[rand(0, $max)]; } return $str; } function startsWith($haystack,$needle) { $length = strlen($needle); return (substr($haystack,0,$length) === $needle); } function endswith($string, $test) { $strlen = strlen($string); $testlen = strlen($test); if ($testlen > $strlen) return false; return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; } function getUserIP() { if(isCloudflare()) return $_SERVER['HTTP_CF_CONNECTING_IP']; $client = @$_SERVER['HTTP_CLIENT_IP']; $forward = @$_SERVER['HTTP_X_FORWARDED_FOR']; $remote = $_SERVER['REMOTE_ADDR']; if(strpos($forward,',')) { $a = explode(',',$forward); $forward = trim($a[0]); } if(filter_var($forward, FILTER_VALIDATE_IP)) { $ip = $forward; } elseif(filter_var($client, FILTER_VALIDATE_IP)) { $ip = $client; } else { $ip = $remote; } return $ip; } // checks the list of uploaded files for this hash function sha1Exists($sha1) { $shafile = getDataDir().DS.'sha1.csv'; if(!file_exists($shafile)) touch($shafile); $handle = fopen($shafile, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { if(substr($line,0,40)===$sha1) return trim(substr($line,41)); } fclose($handle); } return false; } //adds new sha to the hash list function addSha1($hash,$sha1) { if(sha1Exists($sha1)) return; $fp = fopen(getDataDir().DS.'sha1.csv','a'); fwrite($fp,"$sha1;$hash\n"); fclose($fp); return true; } function isSize($var) { if(is_numeric($var)) return true; $a = explode('x',$var); if(count($a)!=2 || !is_numeric($a[0]) || !is_numeric($a[1])) return false; return true; } function isColor($var) { if(strlen($var)==6 && ctype_xdigit($var)) return true; else { $col = color_name_to_hex($var); if($col) return true; else return false; } } function color_name_to_hex($color_name) { // standard 147 HTML color names $colors = array( 'aliceblue'=>'F0F8FF', 'antiquewhite'=>'FAEBD7', 'aqua'=>'00FFFF', 'aquamarine'=>'7FFFD4', 'azure'=>'F0FFFF', 'beige'=>'F5F5DC', 'bisque'=>'FFE4C4', 'black'=>'000000', 'blanchedalmond '=>'FFEBCD', 'blue'=>'0000FF', 'blueviolet'=>'8A2BE2', 'brown'=>'A52A2A', 'burlywood'=>'DEB887', 'cadetblue'=>'5F9EA0', 'chartreuse'=>'7FFF00', 'chocolate'=>'D2691E', 'coral'=>'FF7F50', 'cornflowerblue'=>'6495ED', 'cornsilk'=>'FFF8DC', 'crimson'=>'DC143C', 'cyan'=>'00FFFF', 'darkblue'=>'00008B', 'darkcyan'=>'008B8B', 'darkgoldenrod'=>'B8860B', 'darkgray'=>'A9A9A9', 'darkgreen'=>'006400', 'darkgrey'=>'A9A9A9', 'darkkhaki'=>'BDB76B', 'darkmagenta'=>'8B008B', 'darkolivegreen'=>'556B2F', 'darkorange'=>'FF8C00', 'darkorchid'=>'9932CC', 'darkred'=>'8B0000', 'darksalmon'=>'E9967A', 'darkseagreen'=>'8FBC8F', 'darkslateblue'=>'483D8B', 'darkslategray'=>'2F4F4F', 'darkslategrey'=>'2F4F4F', 'darkturquoise'=>'00CED1', 'darkviolet'=>'9400D3', 'deeppink'=>'FF1493', 'deepskyblue'=>'00BFFF', 'dimgray'=>'696969', 'dimgrey'=>'696969', 'dodgerblue'=>'1E90FF', 'firebrick'=>'B22222', 'floralwhite'=>'FFFAF0', 'forestgreen'=>'228B22', 'fuchsia'=>'FF00FF', 'gainsboro'=>'DCDCDC', 'ghostwhite'=>'F8F8FF', 'gold'=>'FFD700', 'goldenrod'=>'DAA520', 'gray'=>'808080', 'green'=>'008000', 'greenyellow'=>'ADFF2F', 'grey'=>'808080', 'honeydew'=>'F0FFF0', 'hotpink'=>'FF69B4', 'indianred'=>'CD5C5C', 'indigo'=>'4B0082', 'ivory'=>'FFFFF0', 'khaki'=>'F0E68C', 'lavender'=>'E6E6FA', 'lavenderblush'=>'FFF0F5', 'lawngreen'=>'7CFC00', 'lemonchiffon'=>'FFFACD', 'lightblue'=>'ADD8E6', 'lightcoral'=>'F08080', 'lightcyan'=>'E0FFFF', 'lightgoldenrodyellow'=>'FAFAD2', 'lightgray'=>'D3D3D3', 'lightgreen'=>'90EE90', 'lightgrey'=>'D3D3D3', 'lightpink'=>'FFB6C1', 'lightsalmon'=>'FFA07A', 'lightseagreen'=>'20B2AA', 'lightskyblue'=>'87CEFA', 'lightslategray'=>'778899', 'lightslategrey'=>'778899', 'lightsteelblue'=>'B0C4DE', 'lightyellow'=>'FFFFE0', 'lime'=>'00FF00', 'limegreen'=>'32CD32', 'linen'=>'FAF0E6', 'magenta'=>'FF00FF', 'maroon'=>'800000', 'mediumaquamarine'=>'66CDAA', 'mediumblue'=>'0000CD', 'mediumorchid'=>'BA55D3', 'mediumpurple'=>'9370D0', 'mediumseagreen'=>'3CB371', 'mediumslateblue'=>'7B68EE', 'mediumspringgreen'=>'00FA9A', 'mediumturquoise'=>'48D1CC', 'mediumvioletred'=>'C71585', 'midnightblue'=>'191970', 'mintcream'=>'F5FFFA', 'mistyrose'=>'FFE4E1', 'moccasin'=>'FFE4B5', 'navajowhite'=>'FFDEAD', 'navy'=>'000080', 'oldlace'=>'FDF5E6', 'olive'=>'808000', 'olivedrab'=>'6B8E23', 'orange'=>'FFA500', 'orangered'=>'FF4500', 'orchid'=>'DA70D6', 'palegoldenrod'=>'EEE8AA', 'palegreen'=>'98FB98', 'paleturquoise'=>'AFEEEE', 'palevioletred'=>'DB7093', 'papayawhip'=>'FFEFD5', 'peachpuff'=>'FFDAB9', 'peru'=>'CD853F', 'pink'=>'FFC0CB', 'plum'=>'DDA0DD', 'powderblue'=>'B0E0E6', 'purple'=>'800080', 'red'=>'FF0000', 'rosybrown'=>'BC8F8F', 'royalblue'=>'4169E1', 'saddlebrown'=>'8B4513', 'salmon'=>'FA8072', 'sandybrown'=>'F4A460', 'seagreen'=>'2E8B57', 'seashell'=>'FFF5EE', 'sienna'=>'A0522D', 'silver'=>'C0C0C0', 'skyblue'=>'87CEEB', 'slateblue'=>'6A5ACD', 'slategray'=>'708090', 'slategrey'=>'708090', 'snow'=>'FFFAFA', 'springgreen'=>'00FF7F', 'steelblue'=>'4682B4', 'tan'=>'D2B48C', 'teal'=>'008080', 'thistle'=>'D8BFD8', 'tomato'=>'FF6347', 'turquoise'=>'40E0D0', 'violet'=>'EE82EE', 'wheat'=>'F5DEB3', 'white'=>'FFFFFF', 'whitesmoke'=>'F5F5F5', 'yellow'=>'FFFF00', 'yellowgreen'=>'9ACD32'); $color_name = strtolower($color_name); if (isset($colors[$color_name])) return $colors[$color_name]; else return false; } function getStorageControllers() { $controllers = array(); if ($handle = opendir(ROOT.DS.'storage-controllers')) { while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { if(endswith($entry,'.controller.php')) { $controllers[] = ucfirst(substr($entry,0,-15)).'Storage'; include_once(ROOT.DS.'storage-controllers'.DS.$entry); } } } closedir($handle); } return $controllers; } function loadAllContentControllers($all=false) { $allowedcontrollers = false; if(defined('CONTENTCONTROLLERS') && CONTENTCONTROLLERS != '' && $all!==true) { $allowedcontrollers = array_map('strtolower', explode(',',CONTENTCONTROLLERS)); } $controllers = array(); if ($handle = opendir(ROOT.DS.'content-controllers')) { while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { if(is_dir(ROOT.DS.'content-controllers'.DS.$entry) && file_exists(ROOT.DS.'content-controllers'.DS.$entry.DS."$entry.controller.php") && ( ($allowedcontrollers!==false && in_array($entry,$allowedcontrollers) ) || $allowedcontrollers===false)) { $controllers[] = ucfirst($entry).'Controller'; include_once(ROOT.DS.'content-controllers'.DS.$entry.DS."$entry.controller.php"); } } } closedir($handle); } return $controllers; } function getAllContentFiletypes() { $types = array(); $controllers = loadAllContentControllers(); foreach($controllers as $c) { $instance = new $c; if($instance::ctype=='static') $types = array_merge($types,(new $instance)->getRegisteredExtensions()); } return $types; } function rrmdir($dir) { chmod($dir, 0777); if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir."/".$object)) rrmdir($dir."/".$object); else { unlink($dir."/".$object); } } } rmdir($dir); } } function storeFile($srcfile,$hash,$deleteoriginal=false) { if(is_dir(getDataDir().DS.$hash) && file_exists(getDataDir().DS.$hash.DS.$hash)) return; mkdir(getDataDir().DS.$hash); $file = getDataDir().DS.$hash.DS.$hash; copy($srcfile, $file); if($deleteoriginal===true) unlink($srcfile); addSha1($hash,sha1_file($file)); //creating a delete code $deletecode = getRandomString(32); $fh = fopen(getDataDir().DS.$hash.DS.'deletecode', 'w'); fwrite($fh, $deletecode); fclose($fh); if(defined('LOG_UPLOADER') && LOG_UPLOADER) { $fh = fopen(getDataDir().DS.'uploads.csv', 'a'); fwrite($fh, time().';;'.$hash.';'.getUserIP()."\n"); fclose($fh); } return $file; } function getDeleteCodeOfHash($hash) { if(file_exists(getDataDir().DS.$hash.DS.'deletecode')) return file_get_contents(getDataDir().DS.$hash.DS.'deletecode'); return false; } function deleteHash($hash) { //@todo: add hash to deleted list. also on all controllers //delete all files in directory rrmdir(getDataDir().DS.$hash); //tell every storage controller to delete theirs as well $sc = getStorageControllers(); foreach($sc as $contr) { $c = new $contr(); if($c->isEnabled()===true && $c->hashExists($hash)) { $c->deleteFile($hash); } //delete encrypted file if it exists if($c->isEnabled()===true && defined('ENCRYPTION_KEY') && ENCRYPTION_KEY !='' && $c->hashExists($hash.'.enc')) { $c->deleteFile($hash.'.enc'); } } } /** * Check if a given IPv4 or IPv6 is in a network * @param string $ip IP to check in IPV4 format eg. 127.0.0.1 * @param string $range IP/CIDR netmask eg. 127.0.0.0/24, or 2001:db8::8a2e:370:7334/128 * @return boolean true if the ip is in this range / false if not. * via https://stackoverflow.com/a/56050595/1174516 */ function isIPInRange( $ip, $range ) { if(strpos($range,',')!==false) { // we got a list of ranges. splitting $ranges = array_map('trim',explode(',',$range)); foreach($ranges as $range) if(isIPInRange($ip,$range)) return true; return false; } // Get mask bits list($net, $maskBits) = explode('/', $range); // Size $size = (strpos($ip, ':') === false) ? 4 : 16; // Convert to binary $ip = inet_pton($ip); $net = inet_pton($net); if (!$ip || !$net) { throw new InvalidArgumentException('Invalid IP address'); } // Build mask $solid = floor($maskBits / 8); $solidBits = $solid * 8; $mask = str_repeat(chr(255), $solid); for ($i = $solidBits; $i < $maskBits; $i += 8) { $bits = max(0, min(8, $maskBits - $i)); $mask .= chr((pow(2, $bits) - 1) << (8 - $bits)); } $mask = str_pad($mask, $size, chr(0)); // Compare the mask return ($ip & $mask) === ($net & $mask); } function loadContentControllers() { if(defined('CONTENTCONTROLLERS') && CONTENTCONTROLLERS != '') { $controllers = explode(',',CONTENTCONTROLLERS); foreach($controllers as $controller) { $controller = strtolower($controller); if(@file_exists(ROOT . DS . 'content-controllers' . DS. $controller. DS . $controller.'.controller.php')) require_once(ROOT . DS . 'content-controllers' . DS. $controller. DS . $controller.'.controller.php'); } } else loadAllContentControllers(); } function ip_in_range($ip, $range) { if (strpos($range, '/') == false) $range .= '/32'; // $range is in IP/CIDR format eg 127.0.0.1/24 list($range, $netmask) = explode('/', $range, 2); $range_decimal = ip2long($range); $ip_decimal = ip2long($ip); $wildcard_decimal = pow(2, (32 - $netmask)) - 1; $netmask_decimal = ~ $wildcard_decimal; return (($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal)); } // from https://www.cloudflare.com/ips-v4 // and https://www.cloudflare.com/ips-v6 function _cloudflare_CheckIP($ip) { $cf_ips = array_filter(array_map('trim',explode("\n"," 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32 "))); $is_cf_ip = false; foreach ($cf_ips as $cf_ip) { if (ip_in_range($ip, $cf_ip)) { $is_cf_ip = true; break; } } return $is_cf_ip; } function _cloudflare_Requests_Check() { $flag = true; if(!isset($_SERVER['HTTP_CF_CONNECTING_IP'])) $flag = false; if(!isset($_SERVER['HTTP_CF_IPCOUNTRY'])) $flag = false; if(!isset($_SERVER['HTTP_CF_RAY'])) $flag = false; if(!isset($_SERVER['HTTP_CF_VISITOR'])) $flag = false; return $flag; } function isCloudflare() { $ipCheck = _cloudflare_CheckIP($_SERVER['REMOTE_ADDR']); $requestCheck = _cloudflare_Requests_Check(); return ($ipCheck && $requestCheck); } function executeUploadPermission() { if(defined('ALLOWED_SUBNET') && ALLOWED_SUBNET != '' && !isIPInRange( getUserIP(), ALLOWED_SUBNET )) { http_response_code(403); exit(json_encode(array('status'=>'err','reason'=> 'Access denied'))); } else if(defined('UPLOAD_CODE') && UPLOAD_CODE!='') { if(!isset($_REQUEST['uploadcode']) || $_REQUEST['uploadcode']!=UPLOAD_CODE) { http_response_code(403); exit(json_encode(array('status'=>'err','reason'=> 'Incorrect upload code specified - Access denied'))); } } } /** * Checks if a URL is valid * @param string $url * @return boolean (true if valid, false if not) */ function checkURLForPrivateIPRange($url) { $host = getHost($url); $ip = gethostbyname($host); if(is_public_ipv4($ip) || is_public_ipv6($ip)) return false; return true; } function getHost($url){ $URIs = parse_url(trim($url)); $host = !empty($URIs['host'])? $URIs['host'] : explode('/', $URIs['path'])[0]; return $host; } function is_public_ipv4($ip=NULL) { return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) === $ip ? TRUE : FALSE; } function is_public_ipv6($ip=NULL) { return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) === $ip ? TRUE : FALSE; } function getDataDir() { if(defined('SPLITDATA') && SPLITDATA===true && getDomain()) { $dir = ROOT.DS.'data'.DS.getDomain(); if(!is_dir($dir)) mkdir($dir); return $dir; } return ROOT.DS.'data'; } function getDomain($stripport=true) { $host = $_SERVER['HTTP_HOST']; //strip port if(strpos($host,':')!==false) $strippedhost = substr($host,0,strpos($host,':')); //check if it's in ALLOWED_DOMAINS if(defined('ALLOWED_DOMAINS') && ALLOWED_DOMAINS!='') { $domains = explode(',',ALLOWED_DOMAINS); if(!in_array($strippedhost,$domains)) //always check without port return false; else return ($stripport ? $strippedhost : $host); } else return false; } function getURL() { if(defined('URL') && URL !='') return URL; $protocol = strpos(strtolower($_SERVER['SERVER_PROTOCOL']), 'https') === FALSE ? 'http' : 'https'; return $protocol . '://' . getDomain(false).'/'; }