Auction script - Fatal error: Cannot redeclare password_hash()

-Hi,
I’m having trouble with B.I. Media Solutions Auction (phpprobid) , I’m getting the error message:

Fatal error: Cannot redeclare password_hash() in /home/betti397/public_html/includes/functions_login.php on line 147

  1. function password_hash ($password, $salt)
  2. {
  3. return md5(md5($password) . $salt);
  4. }
    I’ve been at it for hours.
    I couldn’t see any obvious errors in functions_login.php but then I’m not much good at PHP code.

Here is the file. I would greatly appreciate it if anyone could “spot the obvious error” for me:

<?


function login_user ($username, $password, $redirect_url = '', $admin_login = false)
{
	global $db, $setts, $signup_fee, $session;

	(array) $login_output = NULL;

	if ($admin_login) ## the spoofer login, we dont need to check for the password here
	{
		logout(false, false);

		$login_query = $db->query("SELECT user_id, username, active, approved, salt, payment_status, is_seller, mail_activated FROM " . DB_PREFIX . "users WHERE
			username='" . $username . "' LIMIT 0,1");
	}
	else
	{
		$salt = $db->get_sql_field("SELECT salt FROM " . DB_PREFIX . "users WHERE username='" . $username . "'", "salt");

		$password_hashed = password_hash($password, $salt);
		
		$password_old = substr(md5($password), 0, 30); ## added for backward compatibility (v5.25 and older versions)

		$login_query = $db->query("SELECT user_id, username, active, approved, salt, 
			payment_status, is_seller, mail_activated FROM " . DB_PREFIX . "users WHERE username='" . $username . "' AND 
			(password='" . $password_hashed . "' OR password='" . $password_old . "') LIMIT 0,1");
	}

	$is_login = $db->num_rows($login_query);

	$login_output['redirect_url'] = 'login.php?invalid_login=1';
	$login_output['user_exists'] = false;

	/**
	 * Important: the redirect to activate_account.php only needs to happen if the signup fee wasnt paid.
	 */

	if ($is_login)
	{
		$login_output = $db->fetch_array($login_query);
		$login_output['user_exists'] = true;

		$login_output['redirect_url'] = (!empty($redirect_url)) ? $redirect_url : 'index.php';

		$login_output['is_seller'] = ($setts['enable_private_site']) ? $login_output['is_seller'] : 1;

		## add signup fee procedure here.
		$signup_result = $signup_fee->signup($login_output['user_id']);

		if ($login_output['active'] == 1 && $login_output['approved'] == 1 && $login_output['mail_activated'] == 1)
		{
			$login_output['active'] = 'Active';
			// now update all shopping carts from the temp session id to the session user id value
			$db->query("UPDATE " . DB_PREFIX . "shopping_carts SET 
				buyer_id=" . $login_output['user_id'] . " WHERE buyer_session_id='" . $session->value('buyer_session_id') . "' AND buyer_session_id!=''");
		}
		else if ($login_output['approved'] == 0 || $login_output['mail_activated'] == 0 || ($signup_result['amount']>0 && $login_output['payment_status'] != 'confirmed')) /* the signup fee wasnt paid, redirect to the payment page */
		{
			$login_output['active'] = null;
			$login_output['redirect_url'] = 'activate_account.php';

			// user_id and username wont be activated either, the user will need to log in again after making the signup fee payment
			$login_output['temp_user_id'] = $login_output['user_id'];
			$login_output['user_id'] = null;
			$login_output['username'] = null;
		}
		else /* means the user is suspended for whichever reason. Members area access is limited. */
		{
			$login_output['active']	= null;
			$login_output['redirect_url'] = 'members_area.php?page=account&section=management';
		}

		## need to fix the function here to see how it handles every situation.
	}

	return $login_output;
}

function login_admin ($username, $password, $pin_generated, $pin_submitted, $check_pin = true)
{
	global $db;

	(array) $login_output = NULL;

	$login_query = $db->query("SELECT * FROM " . DB_PREFIX . "admins WHERE
		username='" . $username . "' AND password='" . md5($password) . "' LIMIT 0,1");

	$is_login = $db->num_rows($login_query);

	if ($is_login)
	{
		$login_details = $db->fetch_array($login_query);

		$valid_pin = ($check_pin) ? check_pin($pin_generated, $pin_submitted) : true;

		if ($valid_pin)
		{
			$login_output['active'] = 'Active';
			$login_output['level'] = $login_details['level'];

			$update_last_login = $db->query("UPDATE " . DB_PREFIX . "admins SET
				date_lastlogin='" . CURRENT_TIME . "' WHERE id='" . $login_details['id'] . "'");
		}
	}

	return $login_output;
}

function logout ($logout_admin = false, $redirect = true)
{
	global $session;

	if ($logout_admin)
	{
		$session->unregister('adminarea');
		$session->unregister('adminlevel');
	}
	else
	{
		$session->unregister('membersarea');
		$session->unregister('username');
		$session->unregister('user_id');
		$session->unregister('is_seller');
		$session->unregister('rm_username');
		$session->unregister('login_store');
		$session->unregister('login_category');
		
		$session->unset_cookie('username_cookie');
	}

	if ($redirect)
	{
		header_redirect('index.php');
	}
}

function password_hash ($password, $salt)
{
	return md5(md5($password) . $salt);
}

function login_spoofer ($username, $admin_username, $admin_password)
{
	global $db;
	(array) $login_output = NULL;

	$login_query = $db->query("SELECT * FROM " . DB_PREFIX . "admins WHERE
		username='" . $admin_username . "' AND password='" . md5($admin_password) . "' AND level='1' LIMIT 0,1");

	$is_login = $db->num_rows($login_query);

	$login_output['admin_exists'] = false;
	if ($is_login)
	{
		$login_output = login_user($username, '', '', true);
		$login_output['admin_exists'] = true;
	}

	return $login_output;
}

?>

PHP (since PHP version 5.5) already includes a function named password_hash. Name your function something else.

1 Like

PHP has a native password_hash function as of version 5.5, so trying to define a function with the same name (without using a namespace) will result in that error you’re getting.

Probably the simplest solution is to rename the function in your code to something that doesn’t conflict with any native functions. Obviously you’ll have to make sure you rename all uses of the function within the code (do a seach and replace). The downside of this is that if you upgrade the script to a new version in the future then your changes will be overwritten and your app will break again.

Also, do not use MD5. In fact, you should just use the built-in password_hash function rather than your own.

Well I think this issue is not that simple, since the OP is using a third party commercial script, something like vBulletin. I am sure the OP did not write any of these functions, which is why hes so confused. I checked the website of PHP Probid, and it confirms my assumption.

Its not recommended for client users to directly alter a third party library code, unless you know what you are doing. This makes future maintenance much more difficult, and some softwares may offer upgrade service which will revert the changes made by client users when they upgrade. Even I refrain from editing third party library source code, unless its not maintained by the original coder anymore, or that I decide to take over its development myself.

Did you report this to the company that sold you this software? What did they say? Maybe they explicitly make it clear that their software cannot run on PHP 5.5+? I think its worth reporting the issue to your software provider, and ask them for a solution. Perhaps their next version will use a different function for password hashing.

1 Like

Such as deleting the really weak one they were using and simply using the one built into PHP instead.

Absolutely get in touch with their support so they can help you resolve the issue. You get full support with your licence so why not use it?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.