<?php /** * Broker * @package Broker */ namespace Broker; /** * Handle authentication based on IP, key or login/password */ class Authentication { /** * Access based on IP * * @var boolean */ private $accessBasedOnIP; /** * Access based on key * * @var boolean */ private $accessBasedOnKey; /** * Access based on login * * @var boolean */ private $accessBasedOnLogin; /** * Access with admin privileges * * @var boolean */ private $accessWithAdminPrivileges; /** * Configuration * * @var object */ private $configuration; /** * Constructor * * @param object $configuration */ public function __construct($configuration) { if ($configuration && is_array ( $configuration )) { $this->configuration = $configuration; } else { $this->configuration = array (); } if (isset ( $_SERVER ["HTTP_X_BROKER_KEY"] )) { $this->accessBasedOnKey = $this->validateKey ( $_SERVER ["HTTP_X_BROKER_KEY"] ); } else { $this->accessBasedOnKey = false; } if (! $this->accessBasedOnKey) { // session $sessionObject = new \Broker\Session ( SITE_CACHE_DATABASE_DIR ); session_set_save_handler ( Array ( $sessionObject, "open" ), Array ( $sessionObject, "close" ), Array ( $sessionObject, "read" ), Array ( $sessionObject, "write" ), Array ( $sessionObject, "destroy" ), Array ( $sessionObject, "gc" ) ); session_name ( "brokerSession" ); session_start (); // checks $this->accessBasedOnIP = $this->validateIP ( $_SERVER ["REMOTE_ADDR"] ); $this->accessBasedOnLogin = isset ( $_SESSION ["login"] ) && $_SESSION ["login"] ? true : false; $this->accessWithAdminPrivileges = isset ( $_SESSION ["admin"] ) && $_SESSION ["admin"] ? true : false; } } /** * Reset */ public function reset() { } /** * Check for access * * @return boolean */ public function access() { return $this->accessBasedOnIP || $this->accessBasedOnKey || $this->accessBasedOnLogin; } /** * Check for access based on IP * * @return boolean */ public function accessBasedOnIP() { return $this->accessBasedOnIP; } /** * Check for access based on key * * @return boolean */ public function accessBasedOnKey() { return $this->accessBasedOnKey; } /** * Check for access based on login * * @return boolean */ public function accessBasedOnLogin() { return $this->accessBasedOnLogin; } /** * Check for access with admin privileges * * @return boolean */ public function accessWithAdminPrivileges() { return $this->accessBasedOnLogin && $this->accessWithAdminPrivileges; } /** * Get ip * * @return string */ public function getIP() { return $_SERVER ["REMOTE_ADDR"]; } /** * Get login * * @return string|boolean */ public function getLogin() { if ($this->accessBasedOnLogin) { return isset ( $_SESSION ["login"] ) ? $_SESSION ["login"] : null; } else { return false; } } /** * Get name * * @return string|boolean */ public function getName() { if ($this->accessBasedOnLogin) { return isset ( $_SESSION ["name"] ) ? $_SESSION ["name"] : null; } else { return false; } } /** * Logout */ public function logout() { $this->accessBasedOnLogin = false; if (isset ( $_SESSION ["login"] ) || isset ( $_SESSION ["name"] )) { $_SESSION ["login"] = null; $_SESSION ["admin"] = null; $_SESSION ["name"] = null; unset ( $_SESSION ["login"] ); unset ( $_SESSION ["admin"] ); unset ( $_SESSION ["name"] ); } } /** * Login * * @param string $login * @param string $name * @param boolean $admin */ private function login($login, $name, $admin) { if (! $login || ! is_string ( $login )) { $this->logout (); } else { $this->accessBasedOnLogin = true; $_SESSION ["login"] = $login; if ($admin && is_bool ( $admin )) { $_SESSION ["admin"] = $login; } else { $_SESSION ["admin"] = null; } $_SESSION ["name"] = $name && is_string ( $name ) ? $name : $login; } } /** * Validate IP * * @param string $ip * @return boolean */ private function validateIP($ip) { if (isset ( $this->configuration ["ip"] ) && is_array ( $this->configuration ["ip"] )) { $list = $this->configuration ["ip"]; $ip = preg_replace ( "/\b0+(?=\d)/", "", $ip ); if (filter_var ( $ip, FILTER_VALIDATE_IP )) { if (filter_var ( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 )) { $ip = ip2long ( $ip ); foreach ( $list as $item ) { if (isset ( $item ["ip"] ) && is_string ( $item ["ip"] )) { if (preg_match ( "/\//", $item ["ip"] )) { list ( $filterIP, $filterRange ) = explode ( "/", $item ["ip"], 2 ); } else { $filterIP = $item ["ip"]; $filterRange = ""; } $filterIP = preg_replace ( "/\b0+(?=\d)/", "", $filterIP ); if (filter_var ( $filterIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 )) { $filterIP = ip2long ( $filterIP ); if ($filterRange != null && $filterRange != "") { if($filterRange==0) { return true; } else if (intval ( $filterRange ) > 0) { $filterRange = intval ( $filterRange ); $min = (($filterIP) & ((- 1 << (32 - $filterRange)))); $max = ((($min)) + pow ( 2, (32 - $filterRange) ) - 1); if ($ip >= $min && $ip <= $max) { return true; } } // die ( long2ip ( $filterIP ) . "/" . $filterRange . " : " . $min . " - " . $max ); } else if ($ip == $filterIP) { return true; } } } } } else if (filter_var ( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 )) { foreach ( $list as $item ) { if (preg_match ( "/\//", $item )) { list ( $filterIP, $filterRange ) = explode ( "/", $item, 2 ); } else { $filterIP = $item; $filterRange = ""; } $filterIP = preg_replace ( "/\b0+(?=\d)/", "", $filterIP ); if (filter_var ( $filterIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 )) { if ($filterRange != null && $filterRange != "" && (intval ( $filterRange ) > 0)) { $filterRange = intval ( $filterRange ); // todo: not supported for now } else if (inet_pton ( $ip ) == inet_pton ( $filterIP )) { return true; } } } } } } return false; } /** * Validate key * * @param string $key * @return bool */ private function validateKey($key) { if ($key && is_string ( $key )) { if (isset ( $this->configuration ["key"] ) && is_array ( $this->configuration ["key"] )) { foreach ( $this->configuration ["key"] as $item ) { if (isset ( $item ["key"] ) && is_string ( $item ["key"] ) && ($item ["key"] == $key)) { return true; } } } } return false; } /** * Validate login * * @param string $login * @param string $password * @return boolean */ public function validateLogin($login, $password) { if ($login && is_string ( $login ) && $password && is_string ( $password )) { if (isset ( $this->configuration ["login"] ) && is_array ( $this->configuration ["login"] )) { $list = $this->configuration ["login"]; $login = mb_strtolower ( $login ); foreach ( $list as $item ) { if (is_array ( $item ) && isset ( $item ["login"] ) && is_string ( $item ["login"] ) && ($login == mb_strtolower ( $item ["login"] ))) { if (isset ( $item ["password"] ) && is_string ( $item ["password"] ) && hash_equals ( $item ["password"], @crypt ( $password, $item ["password"] ) )) { $this->accessBasedOnLogin = true; if (isset ( $item ["admin"] ) && $item ["admin"]) { $this->login ( $item ["login"], $item ["name"], true ); } else { $this->login ( $item ["login"], $item ["name"], false ); } return true; } } } } } return false; } }