This file is indexed.

/usr/share/php/Horde/Token/Base.php is in php-horde-token 2.0.5-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<?php
/**
 * The Horde_Token_Base:: class provides a common abstracted interface for
 * a token implementation.
 *
 * Copyright 2010-2014 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>
 * @author   Chuck Hagenbuch <chuck@horde.org>
 * @category Horde
 * @package  Token
 */
abstract class Horde_Token_Base
{
    /**
     * Hash of parameters necessary to use the chosen backend.
     *
     * @var array
     */
    protected $_params = array();

    /**
     * Constructor.
     *
     * @param array $params  Required parameters:
     * - secret (string): The secret string used for signing tokens.
     * Optional parameters:
     * - token_lifetime (integer): The number of seconds after which tokens
     *                             time out. Negative numbers represent "no
     *                             timeout". The default is "-1".
     * - timeout (integer): The period (in seconds) after which an id is purged.
     *                      DEFAULT: 86400 (24 hours)
     */
    public function __construct($params)
    {
        if (!isset($params['secret'])) {
            throw new Horde_Token_Exception('Missing secret parameter.');
        }

        $params = array_merge(array(
            'token_lifetime' => -1,
            'timeout' => 86400
        ), $params);

        $this->_params = $params;
    }

    /**
     * Checks if the given token has been previously used. First
     * purges all expired tokens. Then retrieves current tokens for
     * the given ip address. If the specified token was not found,
     * adds it.
     *
     * @param string $token  The value of the token to check.
     *
     * @return boolean  True if the token has not been used, false otherwise.
     * @throws Horde_Token_Exception
     */
    public function verify($token)
    {
        $this->purge();

        if ($this->exists($token)) {
            return false;
        }

        $this->add($token);
        return true;
    }

    /**
     * Does the token exist?
     *
     * @param string $tokenID  Token ID.
     *
     * @return boolean  True if the token exists.
     * @throws Horde_Token_Exception
     */
    abstract public function exists($tokenID);

    /**
     * Add a token ID.
     *
     * @param string $tokenID  Token ID to add.
     *
     * @throws Horde_Token_Exception
     */
    abstract public function add($tokenID);

    /**
     * Delete all expired connection IDs.
     *
     * @throws Horde_Token_Exception
     */
    abstract public function purge();

    /**
     * Return a new signed token.
     *
     * @param string $seed  A unique ID to be included in the token.
     *
     * @return string The new token.
     */
    public function get($seed = '')
    {
        $nonce = $this->getNonce();
        return Horde_Url::uriB64Encode(
            $nonce . $this->_hash($nonce . $seed)
        );
    }

    /**
     * Validate a signed token.
     *
     * @param string  $token    The signed token.
     * @param string  $seed     The unique ID of the token.
     * @param int     $timeout  Timout of the token in seconds.
     *                          Values below zero represent no timeout.
     * @param boolean $unique   Should validation of the token succeed only once?
     *
     * @return boolean  True if the token was valid.
     */
    public function isValid($token, $seed = '', $timeout = null,
                            $unique = false)
    {
        list($nonce, $hash) = $this->_decode($token);
        if ($hash != $this->_hash($nonce . $seed)) {
            return false;
        }
        if ($timeout === null) {
            $timeout = $this->_params['token_lifetime'];
        }
        if ($this->_isExpired($nonce, $timeout)) {
            return false;
        }
        if ($unique) {
            return $this->verify($token);
        }
        return true;
    }

    /**
     * Is the given token still valid? Throws an exception in case it is not.
     *
     * @param string  $token    The signed token.
     * @param string  $seed     The unique ID of the token.
     * @param int     $timeout  Timout of the token in seconds.
     *                          Values below zero represent no timeout.
     *
     * @return array An array of two elements: The nonce and the hash.
     *
     * @throws Horde_Token_Exception If the token was invalid.
     */
    public function validate($token, $seed = '', $timeout = null)
    {
        list($nonce, $hash) = $this->_decode($token);
        if ($hash != $this->_hash($nonce . $seed)) {
            throw new Horde_Token_Exception_Invalid(Horde_Token_Translation::t('We cannot verify that this request was really sent by you. It could be a malicious request. If you intended to perform this action, you can retry it now.'));
        }
        if ($timeout === null) {
            $timeout = $this->_params['token_lifetime'];
        }
        if ($this->_isExpired($nonce, $timeout)) {
            throw new Horde_Token_Exception_Expired(sprintf(Horde_Token_Translation::t("This request cannot be completed because the link you followed or the form you submitted was only valid for %s minutes. Please try again now."), floor($timeout / 60)));
        }
        return array($nonce, $hash);
    }

    /**
     * Is the given token valid and has never been used before? Throws an
     * exception otherwise.
     *
     * @param string  $token  The signed token.
     * @param string  $seed   The unique ID of the token.
     *
     * @return NULL
     *
     * @throws Horde_Token_Exception  If the token was invalid or has been
     *                                used before.
     */
    public function validateUnique($token, $seed = '')
    {
        if (!$this->isValid($token, $seed)) {
            throw new Horde_Token_Exception_Used(Horde_Token_Translation::t('This token is invalid!'));
        }

        if (!$this->verify($token)) {
            throw new Horde_Token_Exception_Used(Horde_Token_Translation::t('This token has been used before!'));
        }
    }

    /**
     * Decode a token into the prefixed nonce and the hash.
     *
     * @param string $token The token to be decomposed.
     *
     * @return array An array of two elements: The nonce and the hash.
     */
    private function _decode($token)
    {
        $b = Horde_Url::uriB64Decode($token);
        return array(substr($b, 0, 6), substr($b, 6));
    }

    /**
     * Has the nonce expired?
     *
     * @param string $nonce   The to be checked for expiration.
     * @param int    $timeout The timeout that should be applied.
     *
     * @return boolean True if the nonce expired.
     */
    private function _isExpired($nonce, $timeout)
    {
        $timestamp = unpack('N', substr($nonce, 0, 4));
        $timestamp = array_pop($timestamp);
        return $timeout >= 0 && (time() - $timestamp - $timeout) >= 0;
    }

    /**
     * Sign the given text with the secret.
     *
     * @param string $text The text to be signed.
     *
     * @return string The hashed text.
     */
    private function _hash($text)
    {
        return hash('sha256', $text . $this->_params['secret'], true);
    }

    /**
     * Return a "number used once" (a concatenation of a timestamp and a random
     * numer).
     *
     * @return string A string of 6 bytes.
     */
    public function getNonce()
    {
        return pack('Nn', time(), mt_rand());
    }

    /**
     * Encodes the remote address.
     *
     * @return string  Encoded address.
     */
    protected function _encodeRemoteAddress()
    {
        return isset($_SERVER['REMOTE_ADDR'])
            ? base64_encode($_SERVER['REMOTE_ADDR'])
            : '';
    }
}