Example #1
0
 public static function OnPageStart($use_query = false)
 {
     //ToDo: good candidate for refactoring
     global $DB, $CACHE_MANAGER;
     if (!CSecuritySystemInformation::isCliMode() && CSecurityIPRule::GetActiveCount()) {
         if (CSecurityIPRule::CheckAntiFile()) {
             return;
         }
         $bMatch = false;
         $uri = $_SERVER['REQUEST_URI'];
         if (($pos = strpos($uri, '?')) !== false) {
             $uri = substr($uri, 0, $pos);
         }
         $uri = urldecode($uri);
         $uri = preg_replace('#/+#', '/', $uri);
         //Block any invalid uri
         if (!static::isValidUri($uri)) {
             include $_SERVER['DOCUMENT_ROOT'] . '/bitrix/admin/security_403.php';
         }
         //die inside
         //Normalize on Windows, because my. == my
         if (CSecuritySystemInformation::isRunOnWin()) {
             $uri = preg_replace('#(. )+[/\\\\]+#', '/', $uri);
         }
         $ip2check = CSecurityIPRule::ip2number($_SERVER["REMOTE_ADDR"]);
         if (!$use_query && CACHED_b_sec_iprule !== false) {
             $cache_id = "b_sec_iprule";
             if ($CACHE_MANAGER->Read(CACHED_b_sec_iprule, $cache_id, "b_sec_iprule")) {
                 $arRules = $CACHE_MANAGER->Get($cache_id);
             } else {
                 $arRules = array();
                 $rs = $DB->Query("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tr.ID,\n\t\t\t\t\t\t\tr.ADMIN_SECTION,\n\t\t\t\t\t\t\tr.SITE_ID,\n\t\t\t\t\t\t\tr.ACTIVE_FROM_TIMESTAMP,\n\t\t\t\t\t\t\tr.ACTIVE_TO_TIMESTAMP\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tr.ACTIVE='Y'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tr.ACTIVE_TO IS NULL\n\t\t\t\t\t\t\t\tOR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . "\n\t\t\t\t\t\t\t)\n\t\t\t\t\t");
                 while ($ar = $rs->Fetch()) {
                     $ar["ACTIVE_FROM_TIMESTAMP"] = intval($ar["ACTIVE_FROM_TIMESTAMP"]);
                     $ar["ACTIVE_TO_TIMESTAMP"] = intval($ar["ACTIVE_TO_TIMESTAMP"]);
                     $ar["INCL_MASKS"] = array();
                     $ar["EXCL_MASKS"] = array();
                     $ar["INCL_IPS"] = array();
                     $ar["EXCL_IPS"] = array();
                     $arRules[$ar["ID"]] = $ar;
                 }
                 $rs = $DB->Query("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tim.IPRULE_ID,\n\t\t\t\t\t\t\tim.PREG_MASK\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\t\tINNER JOIN b_sec_iprule_incl_mask im on im.IPRULE_ID = r.ID\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tr.ACTIVE='Y'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tr.ACTIVE_TO IS NULL\n\t\t\t\t\t\t\t\tOR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . "\n\t\t\t\t\t\t\t)\n\t\t\t\t\t");
                 while ($ar = $rs->Fetch()) {
                     if (array_key_exists($ar["IPRULE_ID"], $arRules)) {
                         $arRules[$ar["IPRULE_ID"]]["INCL_MASKS"][] = $ar["PREG_MASK"];
                     }
                 }
                 foreach ($arRules as $ID => $ar) {
                     if (count($ar["INCL_MASKS"]) <= 0) {
                         unset($arRules[$ID]);
                     }
                 }
                 $rs = $DB->Query("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tem.IPRULE_ID,\n\t\t\t\t\t\t\tem.PREG_MASK\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\t\tINNER JOIN b_sec_iprule_excl_mask em on em.IPRULE_ID = r.ID\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tr.ACTIVE='Y'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tr.ACTIVE_TO IS NULL\n\t\t\t\t\t\t\t\tOR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . "\n\t\t\t\t\t\t\t)\n\t\t\t\t\t");
                 while ($ar = $rs->Fetch()) {
                     if (array_key_exists($ar["IPRULE_ID"], $arRules)) {
                         $arRules[$ar["IPRULE_ID"]]["EXCL_MASKS"][] = $ar["PREG_MASK"];
                     }
                 }
                 $rs = $DB->Query("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tii.IPRULE_ID,\n\t\t\t\t\t\t\tii.IP_START,\n\t\t\t\t\t\t\tii.IP_END\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\t\tINNER JOIN b_sec_iprule_incl_ip ii on ii.IPRULE_ID = r.ID\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tr.ACTIVE='Y'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tr.ACTIVE_TO IS NULL\n\t\t\t\t\t\t\t\tOR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . "\n\t\t\t\t\t\t\t)\n\t\t\t\t\t");
                 while ($ar = $rs->Fetch()) {
                     if (array_key_exists($ar["IPRULE_ID"], $arRules)) {
                         $arRules[$ar["IPRULE_ID"]]["INCL_IPS"][] = array(doubleval($ar["IP_START"]), doubleval($ar["IP_END"]));
                     }
                 }
                 foreach ($arRules as $ID => $ar) {
                     if (count($ar["INCL_IPS"]) <= 0) {
                         unset($arRules[$ID]);
                     }
                 }
                 $rs = $DB->Query("\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tei.IPRULE_ID,\n\t\t\t\t\t\t\tei.IP_START,\n\t\t\t\t\t\t\tei.IP_END\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\t\tINNER JOIN b_sec_iprule_excl_ip ei on ei.IPRULE_ID = r.ID\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tr.ACTIVE='Y'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tr.ACTIVE_TO IS NULL\n\t\t\t\t\t\t\t\tOR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . "\n\t\t\t\t\t\t\t)\n\t\t\t\t\t");
                 while ($ar = $rs->Fetch()) {
                     if (array_key_exists($ar["IPRULE_ID"], $arRules)) {
                         $arRules[$ar["IPRULE_ID"]]["EXCL_IPS"][] = array(doubleval($ar["IP_START"]), doubleval($ar["IP_END"]));
                     }
                 }
                 $CACHE_MANAGER->Set($cache_id, $arRules);
             }
             foreach ($arRules as $arRule) {
                 //Check if this rule is active
                 if (($arRule["ACTIVE_FROM_TIMESTAMP"] <= 0 || $arRule["ACTIVE_FROM_TIMESTAMP"] <= time()) && ($arRule["ACTIVE_TO_TIMESTAMP"] <= 0 || $arRule["ACTIVE_TO_TIMESTAMP"] >= time())) {
                     $bMatch = true;
                 } else {
                     $bMatch = false;
                 }
                 //Check if site does match
                 if ($bMatch) {
                     if (defined("ADMIN_SECTION") && ADMIN_SECTION === true) {
                         $bMatch = $arRule["ADMIN_SECTION"] == "Y";
                     } else {
                         $bMatch = !$arRule["SITE_ID"] || $arRule["SITE_ID"] == SITE_ID;
                     }
                 } else {
                     continue;
                 }
                 //Check if IP in blocked
                 if ($bMatch) {
                     $bMatch = false;
                     foreach ($arRule["INCL_IPS"] as $arIP) {
                         if ($ip2check >= $arIP[0] && $ip2check <= $arIP[1]) {
                             $bMatch = true;
                             break;
                         }
                     }
                     //IP is in blocked range so check if it is exluded
                     if ($bMatch) {
                         foreach ($arRule["EXCL_IPS"] as $arIP) {
                             if ($ip2check >= $arIP[0] && $ip2check <= $arIP[1]) {
                                 $bMatch = false;
                                 break;
                             }
                         }
                     }
                 } else {
                     continue;
                 }
                 //IP does match to blocking condition let's check path
                 if ($bMatch) {
                     $bMatch = false;
                     foreach ($arRule["INCL_MASKS"] as $mask) {
                         if (preg_match("#^" . $mask . "\$#", $uri)) {
                             $bMatch = true;
                             break;
                         }
                     }
                     //Check path for exclusion
                     if ($bMatch) {
                         foreach ($arRule["EXCL_MASKS"] as $mask) {
                             if (preg_match("#^" . $mask . "\$#", $uri)) {
                                 $bMatch = false;
                                 break;
                             }
                         }
                     }
                 } else {
                     continue;
                 }
                 //Found blocking rule
                 if ($bMatch) {
                     break;
                 }
             }
         } else {
             $strSql = "\n\t\t\t\t\tSELECT r.ID\n\t\t\t\t\tFROM\n\t\t\t\t\t\tb_sec_iprule r\n\t\t\t\t\t\tINNER JOIN b_sec_iprule_incl_mask im on im.IPRULE_ID = r.ID\n\t\t\t\t\t\tLEFT  JOIN b_sec_iprule_excl_mask em on em.IPRULE_ID = r.ID AND '" . $DB->ForSQL($uri) . "' like em.LIKE_MASK\n\t\t\t\t\t\tINNER JOIN b_sec_iprule_incl_ip   ii on ii.IPRULE_ID = r.ID\n\t\t\t\t\t\tLEFT  JOIN b_sec_iprule_excl_ip   ei on ei.IPRULE_ID = r.ID AND " . $ip2check . " between ei.IP_START and ei.IP_END\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tr.ACTIVE = 'Y'\n\t\t\t\t\t\tAND (r.ACTIVE_FROM IS NULL OR r.ACTIVE_FROM <= " . $DB->CurrentTimeFunction() . ")\n\t\t\t\t\t\tAND (r.ACTIVE_TO IS NULL OR r.ACTIVE_TO >= " . $DB->CurrentTimeFunction() . ")\n\t\t\t\t\t\t" . (defined("ADMIN_SECTION") && ADMIN_SECTION === true ? "AND r.ADMIN_SECTION = 'Y'" : "AND (r.SITE_ID IS NULL OR r.SITE_ID = '" . $DB->ForSQL(SITE_ID) . "')") . "\n\t\t\t\t\t\tAND '" . $DB->ForSQL($uri) . "' like im.LIKE_MASK\n\t\t\t\t\t\tAND em.IPRULE_ID is null\n\t\t\t\t\t\tAND " . $ip2check . " between ii.IP_START and ii.IP_END\n\t\t\t\t\t\tAND ei.IPRULE_ID is null\n\t\t\t\t";
             //echo "<pre>".htmlspecialcharsbx($strSql)."</pre>";
             $rs = $DB->Query($strSql);
             if ($arRule = $rs->Fetch()) {
                 $bMatch = true;
             } else {
                 $bMatch = false;
             }
         }
         if ($bMatch) {
             include $_SERVER["DOCUMENT_ROOT"] . "/bitrix/admin/security_403.php";
         }
     }
 }
Example #2
0
	function OnPageStart($use_query = false)
	{
		global $DB, $CACHE_MANAGER;

		if(CSecurityIPRule::GetActiveCount())
		{
			$bMatch = false;

			if(CSecurityIPRule::CheckAntiFile())
				return;

			$ip2check = CSecurityIPRule::ip2number($_SERVER["REMOTE_ADDR"]);

			if(!$use_query && CACHED_b_sec_iprule !== false)
			{
				$cache_id = "b_sec_iprule";
				if($CACHE_MANAGER->Read(CACHED_b_sec_iprule, $cache_id, "b_sec_iprule"))
				{
					$arRules = $CACHE_MANAGER->Get($cache_id);
				}
				else
				{
					$arRules = array();

					$rs = $DB->Query("
						SELECT
							r.ID,
							r.ADMIN_SECTION,
							r.SITE_ID,
							r.ACTIVE_FROM_TIMESTAMP,
							r.ACTIVE_TO_TIMESTAMP
						FROM
							b_sec_iprule r
						WHERE
							r.ACTIVE='Y'
							AND (
								r.ACTIVE_TO IS NULL
								OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction()."
							)
					");
					while($ar = $rs->Fetch())
					{
						$ar["ACTIVE_FROM_TIMESTAMP"] = intval($ar["ACTIVE_FROM_TIMESTAMP"]);
						$ar["ACTIVE_TO_TIMESTAMP"] = intval($ar["ACTIVE_TO_TIMESTAMP"]);
						$ar["INCL_MASKS"] = array();
						$ar["EXCL_MASKS"] = array();
						$ar["INCL_IPS"] = array();
						$ar["EXCL_IPS"] = array();
						$arRules[$ar["ID"]] = $ar;
					}

					$rs = $DB->Query("
						SELECT
							im.IPRULE_ID,
							im.PREG_MASK
						FROM
							b_sec_iprule r
							INNER JOIN b_sec_iprule_incl_mask im on im.IPRULE_ID = r.ID
						WHERE
							r.ACTIVE='Y'
							AND (
								r.ACTIVE_TO IS NULL
								OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction()."
							)
					");
					while($ar = $rs->Fetch())
						if(array_key_exists($ar["IPRULE_ID"], $arRules))
							$arRules[$ar["IPRULE_ID"]]["INCL_MASKS"][] = $ar["PREG_MASK"];

					foreach($arRules as $ID => $ar)
						if(count($ar["INCL_MASKS"]) <= 0)
							unset($arRules[$ID]);

					$rs = $DB->Query("
						SELECT
							em.IPRULE_ID,
							em.PREG_MASK
						FROM
							b_sec_iprule r
							INNER JOIN b_sec_iprule_excl_mask em on em.IPRULE_ID = r.ID
						WHERE
							r.ACTIVE='Y'
							AND (
								r.ACTIVE_TO IS NULL
								OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction()."
							)
					");
					while($ar = $rs->Fetch())
						if(array_key_exists($ar["IPRULE_ID"], $arRules))
							$arRules[$ar["IPRULE_ID"]]["EXCL_MASKS"][] = $ar["PREG_MASK"];

					$rs = $DB->Query("
						SELECT
							ii.IPRULE_ID,
							ii.IP_START,
							ii.IP_END
						FROM
							b_sec_iprule r
							INNER JOIN b_sec_iprule_incl_ip ii on ii.IPRULE_ID = r.ID
						WHERE
							r.ACTIVE='Y'
							AND (
								r.ACTIVE_TO IS NULL
								OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction()."
							)
					");
					while($ar = $rs->Fetch())
						if(array_key_exists($ar["IPRULE_ID"], $arRules))
							$arRules[$ar["IPRULE_ID"]]["INCL_IPS"][] = array(
								doubleval($ar["IP_START"]),
								doubleval($ar["IP_END"]),
							);

					foreach($arRules as $ID => $ar)
						if(count($ar["INCL_IPS"]) <= 0)
							unset($arRules[$ID]);

					$rs = $DB->Query("
						SELECT
							ei.IPRULE_ID,
							ei.IP_START,
							ei.IP_END
						FROM
							b_sec_iprule r
							INNER JOIN b_sec_iprule_excl_ip ei on ei.IPRULE_ID = r.ID
						WHERE
							r.ACTIVE='Y'
							AND (
								r.ACTIVE_TO IS NULL
								OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction()."
							)
					");
					while($ar = $rs->Fetch())
						if(array_key_exists($ar["IPRULE_ID"], $arRules))
							$arRules[$ar["IPRULE_ID"]]["EXCL_IPS"][] = array(
								doubleval($ar["IP_START"]),
								doubleval($ar["IP_END"]),
							);

					$CACHE_MANAGER->Set($cache_id, $arRules);
				}

				foreach($arRules as $arRule)
				{
					//Check if this rule is active
					if(
						($arRule["ACTIVE_FROM_TIMESTAMP"] <= 0 || $arRule["ACTIVE_FROM_TIMESTAMP"] <= time())
						&& ($arRule["ACTIVE_TO_TIMESTAMP"] <= 0 || $arRule["ACTIVE_TO_TIMESTAMP"] >= time())
					)
					{
						$bMatch = true;
					}
					else
					{
						$bMatch = false;
					}

					//Check if site does match
					if($bMatch)
					{
						if(defined("ADMIN_SECTION") && ADMIN_SECTION===true)
							$bMatch = $arRule["ADMIN_SECTION"] == "Y";
						else
							$bMatch = (strlen($arRule["SITE_ID"]) <= 0) || ($arRule["SITE_ID"] = SITE_ID);
					}
					else
					{
						continue;
					}

					//Check if IP in blocked
					if($bMatch)
					{
						$bMatch = false;
						foreach($arRule["INCL_IPS"] as $arIP)
						{
							if($ip2check >= $arIP[0] && $ip2check <= $arIP[1])
							{
								$bMatch = true;
								break;
							}
						}
						//IP is in blocked range so check if it is exluded
						if($bMatch)
						{
							foreach($arRule["EXCL_IPS"] as $arIP)
							{
								if($ip2check >= $arIP[0] && $ip2check <= $arIP[1])
								{
									$bMatch = false;
									break;
								}
							}
						}
					}
					else
					{
						continue;
					}

					//IP does match to blocking condition let's check path
					if($bMatch)
					{
						$bMatch = false;
						foreach($arRule["INCL_MASKS"] as $mask)
						{
							if(preg_match("#^".$mask."$#", $_SERVER["REQUEST_URI"]))
							{
								$bMatch = true;
								break;
							}
						}
						//Check path for exclusion
						if($bMatch)
						{
							foreach($arRule["EXCL_MASKS"] as $mask)
							{
								if(preg_match("#^".$mask."$#", $_SERVER["REQUEST_URI"]))
								{
									$bMatch = false;
									break;
								}
							}
						}
					}
					else
					{
						continue;
					}

					//Found blocking rule
					if($bMatch)
						break;
				}
			}
			else
			{
				$strSql = "
					SELECT r.ID
					FROM
						b_sec_iprule r
						INNER JOIN b_sec_iprule_incl_mask im on im.IPRULE_ID = r.ID
						LEFT  JOIN b_sec_iprule_excl_mask em on em.IPRULE_ID = r.ID AND '".$DB->ForSQL($_SERVER["REQUEST_URI"])."' like em.LIKE_MASK
						INNER JOIN b_sec_iprule_incl_ip   ii on ii.IPRULE_ID = r.ID
						LEFT  JOIN b_sec_iprule_excl_ip   ei on ei.IPRULE_ID = r.ID AND ".$ip2check." between ei.IP_START and ei.IP_END
					WHERE
						r.ACTIVE = 'Y'
						AND (r.ACTIVE_FROM IS NULL OR r.ACTIVE_FROM <= ".$DB->CurrentTimeFunction().")
						AND (r.ACTIVE_TO IS NULL OR r.ACTIVE_TO >= ".$DB->CurrentTimeFunction().")
						".(defined("ADMIN_SECTION") && ADMIN_SECTION===true?
							"AND r.ADMIN_SECTION = 'Y'":
							"AND (r.SITE_ID IS NULL OR r.SITE_ID = '".$DB->ForSQL(SITE_ID)."')"
						)."
						AND '".$DB->ForSQL($_SERVER["REQUEST_URI"])."' like im.LIKE_MASK
						AND em.IPRULE_ID is null
						AND ".$ip2check." between ii.IP_START and ii.IP_END
						AND ei.IPRULE_ID is null
				";
				//echo "<pre>".htmlspecialcharsbx($strSql)."</pre>";
				$rs = $DB->Query($strSql);

				if($arRule = $rs->Fetch())
					$bMatch = true;
				else
					$bMatch = false;
			}

			if($bMatch)
				include($_SERVER["DOCUMENT_ROOT"]."/bitrix/admin/security_403.php");

		}
	}