<?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;
}
}