forgot password script without dictionary

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
cantthinkofaname
Forum Newbie
Posts: 2
Joined: Thu Jul 22, 2004 5:07 pm

forgot password script without dictionary

Post by cantthinkofaname »

Hi, I am trying to get a forgot_password script to work using a random generator. I use this script on another server with the get

Code: Select all

$dictionary = '/usr/dict/words';  // the ispell dictionary
  $fp = fopen($dictionary, 'r');
  $size = filesize($dictionary);
but the server where this new script is going does not have a dictionary on it for me to use, so I thought about a random generator, found a script on the internet, but it doesn't work. when it gets to my forgot_passwd.php page, it hangs. Anyone know of a way for me to get this to work?

Code: Select all

<?php 

require_once('db_fns.php'); 

function register($email,$passwd,$secretquestion,$secretans
wer,$fname,$mname,$lname,$title,$company,$street,$
city,$state,$zip,$businesstype,$howlearned,$phone,
$faxphone,$cellphone,$membercategory,$paymentmetho
d,$website,$phonetocall,$timetocall) 
// register new person with db 
// return true or error message 
{ 
// connect to db 
$conn = db_connect(); 
if (!$conn) 
return 'Could not connect to database server - please try later.'; 

// check if username is unique 
$result = mysql_query("select * from mytable_tbl where email='$email'"); 
if (!$result) 
return 'Could not execute query'; 
if (mysql_num_rows($result)>0) 
return 'That username is taken - go back and choose another one.'; 

// if ok, put in db 
$result = mysql_query("insert into mytable_tbl values 
('$email',password('$passwd'),'$secretquestion','$
secretanswer','$fname','$mname','$lname','$title',
'$company','$street','$city','$state','$zip','$bus
inesstype','$howlearned','$phone','$faxphone','$ce
llphone','$membercategory','$paymentmethod','$webs
ite','$phonetocall','$timetocall',0)"); 
if (!$result) 
return 'Could not register you in database - please try again later.'; 

return true; 
} 

function login($email, $passwd) 
// check username and password with db 
// if yes, return true 
// else return false 
{ 
// connect to db 
$conn = db_connect(); 
if (!$conn) 
return false; 

// check if username is unique 
$result = mysql_query("select * from mytable_tbl 
where email='$email' 
and passwd = password('$passwd') 
and paidflag > '0'"); 
if (!$result) 
return false; 

if (mysql_num_rows($result)>0) 
return true; 
else 
return false; 
} 

function confirm($email, $passwd, $confirm) 
// check username and password with db 
// if yes, update paidflag and return true 
// else return false 
{ 
// connect to db 
$conn = db_connect(); 
if (!$conn) 
return false; 

// check if username is valid 
$result = mysql_query("select * from mytable_tbl 
where email='$email' 
and passwd = password('$passwd') 
and paidflag = '0'"); 

if (!$result) 
return false; 
else 
{ 
if (mysql_num_rows($result)>0) 
{ 
$result = mysql_query("update mytable_tbl 
set paidflag='$confirm' 
where email='$email'");	
return true; 
} 
else 
return false; 
} 
} 

function check_valid_user() 
// see if somebody is logged in and notify them if not 
{ 
global $HTTP_SESSION_VARS; 
if (isset($HTTP_SESSION_VARS['valid_user'])) 
{ 
return; 
} 
else 
{ 
// they are not logged in 
echo 'PROBLEM:'; 
echo 'You are not logged in.<br />'; 
do_html_url('memberlogin.php', 'Login'); 
exit; 
} 
} 

function change_password($username, $old_password, $new_password) 
// change password for username/old_password to new_password 
// return true or false 
{ 
// if the old password is right 
// change their password to new_password and return true 
// else return false 
if (login($email, $old_password)) 
{ 
if (!($conn = db_connect())) 
return false; 
$result = mysql_query( "update mytable_tbl 
set passwd = password('$new_password') 
where email = '$email'"); 
if (!$result) 
return false; // not changed 
else 
return true; // changed successfully 
} 
else 
return false; // old password was wrong 
} 

function get_random_word($min_length, $max_length)
 { 
    //determine the actual length of the word 
    $length = mt_rand($min_length,$max_length); 
    $word = ''; 
    for($i=0;$i<$length;$i++) { 
        $gen_what = mt_rand(1,3); 
        switch ($gen_what) { 
            //append an upper case letter to the word 
            case 1: 
                $word .= chr(rand(65,90)); 
                break; 
            //append an lower case letter to the word 
            case 2: 
                $word .= chr(rand(97,122)); 
                break; 
            //append a number to the word 
            case 3: 
                $word .= chr(rand(48,57)); 
                break; 
        } //end switch 
    } //end for 
    return $word; 
} 


function reset_password($email) 
// set password for username to a random value 
// return the new password or false on failure 
{ 
// get a random dictionary word b/w 6 and 13 chars in length 
$new_password = get_random_word(6, 13); 

if($new_password==false) 
return false; 
// add a number between 0 and 999 to it 
// to make it a slightly better password 
srand ((double) microtime() * 1000000); 
$rand_number = rand(0, 999); 
$new_password .= $rand_number; 

// set user's password to this in database or return false 
if (!($conn = db_connect())) 
return false; 
$result = mysql_query( "update mytable_tbl 
set passwd = password('$new_password') 
where email = '$email'"); 
if (!$result) 
return false; // not changed 
else 
return $new_password; // changed successfully 
} 

function notify_password($email, $passwd) 
// notify the user that their password has been changed 
{ 
if (!($conn = db_connect())) 
return false; 
$result = mysql_query("select email from mytable_tbl 
where email='$email'"); 
if (!$result) 
{ 
return false; // not changed 
} 
else if (mysql_num_rows($result)==0) 
{ 
return false; // username not in db 
} 
else 
{ 
$email = mysql_result($result, 0, 'email'); 
$from = "From: support@mydomaineheh.com \r\n"; 
$mesg = "Yourpassword has been changed to $password \r\n" 
."Please change it next time you log in. \r\n"; 


if (mail($email, 'Your login information', $mesg, $from)) 
return true; 
else 
return false; 
} 
} 

?>
thanks
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

could you help us in telling us where it hangs? that's a lot of code to read to see if there are errors..

a few things stuck out.. "global $HTTP_SESSION_VARS" isn't needed, and may create unexpected results; Additionally, there's no session_start() call on the page, session variables won't be available unless the session has started..
cantthinkofaname
Forum Newbie
Posts: 2
Joined: Thu Jul 22, 2004 5:07 pm

Post by cantthinkofaname »

below is the code I added for the get random word. it never resets the password, so i imagine it is here.

Code: Select all

function get_random_word($min_length, $max_length) { 
    //determine the actual length of the word 
    $length = mt_rand($min_length,$max_length); 
    $word = ''; 
    for($i=0;$i<$length;$i++) { 
        $gen_what = mt_rand(1,3); 
        switch ($gen_what) { 
            //append an upper case letter to the word 
            case 1: 
                $word .= chr(rand(65,90)); 
                break; 
            //append an lower case letter to the word 
            case 2: 
                $word .= chr(rand(97,122)); 
                break; 
            //append a number to the word 
            case 3: 
                $word .= chr(rand(48,57)); 
                break; 
        } //end switch 
    } //end for 
    return $word; 
}


function reset_password($email)
// set password for username to a random value
// return the new password or false on failure
{ 
  // get a random dictionary word b/w 6 and 13 chars in length
  $new_password = get_random_word(6, 13);
  
  if($new_password==false)
    return false;
  // add a number  between 0 and 999 to it
  // to make it a slightly better password
  srand ((double) microtime() * 1000000);
  $rand_number = rand(0, 999); 
  $new_password .= $rand_number;
below is the code on my forgot_passwd.php page.

Code: Select all

<?php
  require_once("regauth2_fns.php");

  //creating short variable name
  $email = $HTTP_POST_VARS['email'];
  $secretquestion = $HTTP_POST_VARS['secretquestion'];
  $secretanswer = $HTTP_POST_VARS['secretanswer'];

  // connect to db
  $conn = db_connect();
  if (!$conn)
    return 'Could not connect to database server - please try later.';

	$result = mysql_query("SELECT * FROM mytable_tbl WHERE email='$email' AND secretquestion='$secretquestion' AND secretanswer='$secretanswer'"); 
	if (!$result)
	   	echo 'Could not execute query - use the back button to try again<br>';
	else
	{
  		if (mysql_num_rows($result)==0)
			echo 'We could not reset your password do to an invalid entry - use the back button and try again';
		else
		{
  			if ($passwd=reset_password($email))
  			{ 
    			if (notify_password($email, $passwd))
      				echo 'Your new password has been sent to your email address.';
    			else
      				echo 'Your password could not be mailed to you. Try pressing refresh.';
  			}
  			else
    			echo 'Your password could not be reset - please try again later.';
		}
	}
?>
I never get an error message, just a blank page on the forgot_passwd.php page.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I just noticed change_password() is never closed.

You may be getting an error in your logs, depending on the status of error_reporting and display_errors
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

You should never base your password on dictionary words. They should be completely random. Try this:

Code: Select all

$password_length = 8;
$acceptable_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$new_password = substr(str_shuffle($acceptable_chars),0,$password_length);
Manual entries on:
[php_man]substr[/php_man]
[php_man]str_shuffle[/php_man]
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Joe
Forum Regular
Posts: 939
Joined: Sun Feb 29, 2004 1:26 pm
Location: UK - Glasgow

Post by Joe »

Code: Select all

$buffer = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$password = substr(str_shuffle($buffer),$buffer,6);
You had a wrong parameter count there pickle. The above code works right!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

[php_man]substr[/php_man] wrote:string substr ( string string, int start [, int length])
that sure looks like pickle had it right, and yours would potentially have problems.. Although that depends on the second argument getting converted to an integer or not..
User avatar
Joe
Forum Regular
Posts: 939
Joined: Sun Feb 29, 2004 1:26 pm
Location: UK - Glasgow

Post by Joe »

Well I actually tested it when I saw this post with pickles version which had the error, wrong parameter count. I fixed it up a bit and worked perfect!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

uh ok.. his has 3 arguments passed to substr, substr accepts 3 arguments. I don't see where there would be a wrong param count...
kettle_drum
DevNet Resident
Posts: 1150
Joined: Sun Jul 20, 2003 9:25 pm
Location: West Yorkshire, England

Post by kettle_drum »

I use this same sort of method to create random ids and what annoys me about it is that since you are just shuffling the chars around you cant have more than one occurence of a char which vastly reduces the strength of it. Guess i should write something better....

[end pointless rant]

(sorry got carried away there)
User avatar
Joe
Forum Regular
Posts: 939
Joined: Sun Feb 29, 2004 1:26 pm
Location: UK - Glasgow

Post by Joe »

uh ok.. his has 3 arguments passed to substr, substr accepts 3 arguments. I don't see where there would be a wrong param count...
Strange, your right with the amount of parameters but its probably because I have that extra colon just after substr()
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

could generate a random repeat of each character like so:

Code: Select all

<?php

$alnum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ0123456789';
$pool = '';
$password_length = 8;
for($x = 0, $y = strlen($alnum); $x < $y; $x++)
  if($len = mt_rand(0,4))
    $pool = str_repeat($alnum{$x}, $len);
$new_password = substr( str_shuffle( $pool ), 0, $password_length );

?>
User avatar
ol4pr0
Forum Regular
Posts: 926
Joined: Thu Jan 08, 2004 11:22 am
Location: ecuador

Post by ol4pr0 »

bit simple maby but i rather like this

Code: Select all

$new = '';
$i = '8';
while ($i--) { 
$new .=chr(mt_rand(33,126));
}
echo $new; #new pass
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

which would work fine if you wanted all printable characters.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Weird, I dunno why mine didn't work for you ~Joe, it has the same parameter count as yours. :?

Anyway, this should work for generating a password with random characters, with the possibilty of duplicate characters.

Code: Select all

$acceptable_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$password_length = 8;
for($i = 0;$i < $password_length;$i++)
{
    $new_pass .= substr($acceptable_chars,rand(),1);
}
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
Post Reply