public function generate_token($form_id = 'phpfusion', $max_tokens = 10, $file = "")
{
global $defender;
$userdata = fusion_get_userdata();
$user_id = iMEMBER ? $userdata['user_id'] : 0;
// store just one token for each form if the user is a guest
if ($user_id == 0) {
$max_tokens = 1;
}
if (isset($_POST['fusion_token']) && $defender->tokenIsValid && $form_id == stripinput($_POST['form_id'])) {
/**
* Attempt to recover the token instead of generating a new one
* Checks if a token is being posted and if is valid, and then
* checks if the form for which this token was intended is
* the same form for which we are trying to generate a token
*/
$token = stripinput($_POST['fusion_token']);
if ($defender->debug) {
addNotice('success', 'The token for "' . stripinput($_POST['form_id']) . '" has been recovered and is being reused');
}
$defender->recycled_token = $token;
} else {
$token_time = time();
$algo = fusion_get_settings('password_algorithm');
$key = $user_id . $token_time . $form_id . SECRET_KEY;
$salt = md5(isset($userdata['user_salt']) ? $userdata['user_salt'] . SECRET_KEY_SALT : SECRET_KEY_SALT);
// generate a new token
$token = $user_id . "." . $token_time . "." . hash_hmac($algo, $key, $salt);
// store the token in session
$_SESSION['csrf_tokens'][self::pageHash($file)][$form_id][] = $token;
if ($defender->debug) {
if (!$defender->safe()) {
addNotice('danger', 'FUSION NULL is DECLARED');
}
if (!empty($_SESSION['csrf_tokens'][self::pageHash($file)][$form_id])) {
addNotice('danger', 'Current Token That is Going to be validated in this page: ');
addNotice('danger', $_SESSION['csrf_tokens'][self::pageHash($file)][$form_id]);
// is not going to be able to read the new one.
} else {
addNotice('warning', 'There is no token for this page this round');
}
}
// some cleaning, remove oldest token if there are too many
if (count($_SESSION['csrf_tokens'][self::pageHash($file)][$form_id]) > $max_tokens) {
if ($defender->debug) {
addNotice('warning', 'Token that is <b>erased</b> ' . $_SESSION['csrf_tokens'][self::pageHash($file)][$form_id][0] . '. This token cannot be validated anymore.');
}
array_shift($_SESSION['csrf_tokens'][self::pageHash($file)][$form_id]);
}
if ($defender->debug) {
if (!empty($_SESSION['csrf_tokens'][self::pageHash($file)][$form_id])) {
addNotice('danger', "After clean up, the token remaining is on " . $form_id . " is -- ");
addNotice('danger', $_SESSION['csrf_tokens'][self::pageHash($file)][$form_id]);
} else {
addNotice('warning', 'There is no token for this page this round');
}
}
}
return $token;
}