170 lines
4.2 KiB
PHP
170 lines
4.2 KiB
PHP
<?php
|
|
/**
|
|
* Token tracking implementation for local files.
|
|
*
|
|
* Copyright 1999-2016 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (LGPL). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
|
|
*
|
|
* @author Max Kalika <max@horde.org>
|
|
* @category Horde
|
|
* @package Token
|
|
*/
|
|
class Horde_Token_File extends Horde_Token_Base
|
|
{
|
|
/* File prefix constant. */
|
|
const FILE_PREFIX = 'conn_';
|
|
|
|
/**
|
|
* Handle for the open file descriptor.
|
|
*
|
|
* @var resource
|
|
*/
|
|
protected $_fd = false;
|
|
|
|
/**
|
|
* Boolean indicating whether or not we have an open file descriptor.
|
|
*
|
|
* @var boolean
|
|
*/
|
|
protected $_connected = false;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @see Horde_Token_Base::__construct() for more parameters.
|
|
*
|
|
* @param array $params Optional parameters:
|
|
* - token_dir (string): The directory where to keep token files.
|
|
* DEFAULT: System temporary directory
|
|
*/
|
|
public function __construct($params = array())
|
|
{
|
|
$params = array_merge(array(
|
|
'token_dir' => sys_get_temp_dir()
|
|
), $params);
|
|
|
|
parent::__construct($params);
|
|
}
|
|
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
try {
|
|
$this->_disconnect(false);
|
|
} catch (Horde_Token_Exception $e) {
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete all expired connection IDs.
|
|
*
|
|
* @throws Horde_Token_Exception
|
|
*/
|
|
public function purge()
|
|
{
|
|
// Make sure we have no open file descriptors before unlinking
|
|
// files.
|
|
$this->_disconnect();
|
|
|
|
/* Build stub file list. */
|
|
try {
|
|
$di = new DirectoryIterator($this->_params['token_dir']);
|
|
} catch (UnexpectedValueException $e) {
|
|
throw new Horde_Token_Exception('Unable to open token directory');
|
|
}
|
|
|
|
/* Find expired stub files */
|
|
foreach ($di as $val) {
|
|
if ($val->isFile() &&
|
|
(strpos($val, self::FILE_PREFIX) === 0) &&
|
|
(time() - $val->getMTime() >= $this->_params['timeout']) &&
|
|
!@unlink($val->getPathname())) {
|
|
throw new Horde_Token_Exception('Unable to purge token file.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Does the token exist?
|
|
*
|
|
* @param string $tokenID Token ID.
|
|
*
|
|
* @return boolean True if the token exists.
|
|
* @throws Horde_Token_Exception
|
|
*/
|
|
public function exists($tokenID)
|
|
{
|
|
$this->_connect();
|
|
|
|
/* Find already used IDs. */
|
|
$token = base64_encode($tokenID);
|
|
foreach (file($this->_params['token_dir'] . '/' . self::FILE_PREFIX . $this->_encodeRemoteAddress()) as $val) {
|
|
if (rtrim($val) == $token) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Add a token ID.
|
|
*
|
|
* @param string $tokenID Token ID to add.
|
|
*
|
|
* @throws Horde_Token_Exception
|
|
*/
|
|
public function add($tokenID)
|
|
{
|
|
$this->_connect();
|
|
|
|
/* Write the entry. */
|
|
$token = base64_encode($tokenID);
|
|
fwrite($this->_fd, $token . "\n");
|
|
|
|
$this->_disconnect();
|
|
}
|
|
|
|
/**
|
|
* Opens a file descriptor to a new or existing file.
|
|
*
|
|
* @throws Horde_Token_Exception
|
|
*/
|
|
protected function _connect()
|
|
{
|
|
if ($this->_connected) {
|
|
return;
|
|
}
|
|
|
|
// Open a file descriptor to the token stub file.
|
|
$this->_fd = @fopen($this->_params['token_dir'] . '/' . self::FILE_PREFIX . $this->_encodeRemoteAddress(), 'a');
|
|
if (!$this->_fd) {
|
|
throw new Horde_Token_Exception('Failed to open token file.');
|
|
}
|
|
|
|
$this->_connected = true;
|
|
}
|
|
|
|
/**
|
|
* Closes the file descriptor.
|
|
*
|
|
* @param boolean $error Throw exception on error?
|
|
*
|
|
* @throws Horde_Token_Exception
|
|
*/
|
|
protected function _disconnect($error = true)
|
|
{
|
|
if ($this->_connected) {
|
|
$this->_connected = false;
|
|
if (!fclose($this->_fd) && $error) {
|
|
throw new Horde_Token_Exception('Unable to close file descriptors');
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|