diff options
author | Andreas Gohr <andi@splitbrain.org> | 2006-07-14 13:05:48 +0200 |
---|---|---|
committer | Andreas Gohr <andi@splitbrain.org> | 2006-07-14 13:05:48 +0200 |
commit | 1d5856cfe64e778c70fece0d08d36f153be16600 (patch) | |
tree | 0d13fa843fd2693cd5c9c0a5d97865f5a92cdb1f | |
parent | 75e487e9d106f5e0a60b5b66552c332c79637442 (diff) | |
download | rpg-1d5856cfe64e778c70fece0d08d36f153be16600.tar.gz rpg-1d5856cfe64e778c70fece0d08d36f153be16600.tar.bz2 |
two-stage password reset
This patch changes the password reset function to a two-stage process.
After requesting a new password a confirmation email is sent first, only
if the link contained in this mail is used the password is changed for real.
This makes sure malicious people can't reset passwords for other users.
darcs-hash:20060714110548-7ad00-c1e23fd51cc2d2f16473914421ebe0f9c3b2ba8c.gz
-rw-r--r-- | conf/dokuwiki.php | 2 | ||||
-rw-r--r-- | inc/auth.php | 101 | ||||
-rw-r--r-- | inc/html.php | 4 | ||||
-rw-r--r-- | inc/lang/en/lang.php | 2 | ||||
-rw-r--r-- | inc/lang/en/password.txt | 20 | ||||
-rw-r--r-- | inc/lang/en/pwconfirm.txt | 15 | ||||
-rw-r--r-- | inc/lang/en/resendpwd.txt | 7 |
7 files changed, 112 insertions, 39 deletions
diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php index dbba11efc..48f33a940 100644 --- a/conf/dokuwiki.php +++ b/conf/dokuwiki.php @@ -59,7 +59,7 @@ $conf['passcrypt'] = 'smd5'; //Used crypt method (smd5,md5,sha1,ssha $conf['defaultgroup']= 'user'; //Default groups new Users are added to $conf['superuser'] = '!!not set!!'; //The admin can be user or @group $conf['profileconfirm'] = '1'; //Require current password to confirm changes to user profile -$conf['disableactions'] = 'resendpwd'; //comma separated list of actions to disable +$conf['disableactions'] = ''; //comma separated list of actions to disable /* Advanced Options */ $conf['userewrite'] = 0; //this makes nice URLs: 0: off 1: .htaccess 2: internal diff --git a/inc/auth.php b/inc/auth.php index 345a2ba67..467f4b0cd 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -570,8 +570,14 @@ function updateprofile() { /** * Send a new password * + * This function handles both phases of the password reset: + * + * - handling the first request of password reset + * - validating the password reset auth token + * * @author Benoit Chesneau <benoit@bchesneau.info> * @author Chris Smith <chris@jalakai.co.uk> + * @author Andreas Gohr <andi@splitbrain.org> * * @return bool true on success, false on any error */ @@ -580,40 +586,89 @@ function act_resendpwd(){ global $conf; global $auth; - if(!$_POST['save']) return false; if(!actionOK('resendpwd')) return false; // should not be able to get here without modPass being possible... if(!$auth->canDo('modPass')) { - msg($lang['resendna'],-1); - return false; + msg($lang['resendna'],-1); + return false; } - if (empty($_POST['login'])) { - msg($lang['resendpwdmissing'], -1); - return false; - } else { - $user = $_POST['login']; - } + $token = preg_replace('/[^a-f0-9]+/','',$_REQUEST['pwauth']); - $userinfo = $auth->getUserData($user); - if(!$userinfo['mail']) { - msg($lang['resendpwdnouser'], -1); - return false; - } + if($token){ + // we're in token phase - $pass = auth_pwgen(); - if (!$auth->modifyUser($user,array('pass' => $pass))) { - msg('error modifying user data',-1); - return false; - } + $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth'; + if(!@file_exists($tfile)){ + msg($lang['resendpwdbadauth'],-1); + return false; + } + $user = io_readfile($tfile); + @unlink($tfile); + $userinfo = $auth->getUserData($user); + if(!$userinfo['mail']) { + msg($lang['resendpwdnouser'], -1); + return false; + } + + $pass = auth_pwgen(); + if (!$auth->modifyUser($user,array('pass' => $pass))) { + msg('error modifying user data',-1); + return false; + } + + if (auth_sendPassword($user,$pass)) { + msg($lang['resendpwdsuccess'],1); + } else { + msg($lang['regmailfail'],-1); + } + return true; - if (auth_sendPassword($user,$pass)) { - msg($lang['resendpwdsuccess'],1); } else { - msg($lang['regmailfail'],-1); + // we're in request phase + + if(!$_POST['save']) return false; + + if (empty($_POST['login'])) { + msg($lang['resendpwdmissing'], -1); + return false; + } else { + $user = $_POST['login']; + } + + $userinfo = $auth->getUserData($user); + if(!$userinfo['mail']) { + msg($lang['resendpwdnouser'], -1); + return false; + } + + // generate auth token + $token = md5(auth_cookiesalt().$user); //secret but user based + $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth'; + $url = wl('',array('do'=>'resendpwd','pwauth'=>$token),true,'&'); + + io_saveFile($tfile,$user); + + $text = rawLocale('pwconfirm'); + $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text); + $text = str_replace('@FULLNAME@',$userinfo['name'],$text); + $text = str_replace('@LOGIN@',$user,$text); + $text = str_replace('@TITLE@',$conf['title'],$text); + $text = str_replace('@CONFIRM@',$url,$text); + + if(mail_send($userinfo['name'].' <'.$userinfo['mail'].'>', + $lang['regpwmail'], + $text, + $conf['mailfrom'])){ + msg($lang['resendpwdconfirm'],1); + }else{ + msg($lang['regmailfail'],-1); + } + return true; } - return true; + + return false; // never reached } /** diff --git a/inc/html.php b/inc/html.php index 9fed619a8..58199e1cd 100644 --- a/inc/html.php +++ b/inc/html.php @@ -78,14 +78,14 @@ function html_login(){ if($auth->canDo('addUser') && actionOK('register')){ print '<p>'; print $lang['reghere']; - print ': <a href="'.wl($ID,'do=register').'" class="wikilink1">'.$lang['register'].'</a>'; + print ': <a href="'.wl($ID,'do=register').'" rel="nofollow" class="wikilink1">'.$lang['register'].'</a>'; print '</p>'; } if ($auth->canDo('modPass') && actionOK('resendpwd')) { print '<p>'; print $lang['pwdforget']; - print ': <a href="'.wl($ID,'do=resendpwd').'" class="wikilink1">'.$lang['btn_resendpwd'].'</a>'; + print ': <a href="'.wl($ID,'do=resendpwd').'" rel="nofollow" class="wikilink1">'.$lang['btn_resendpwd'].'</a>'; print '</p>'; } ?> diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php index ff2e7cd84..894a4176b 100644 --- a/inc/lang/en/lang.php +++ b/inc/lang/en/lang.php @@ -78,6 +78,8 @@ $lang['resendna'] = 'This wiki does not support password resending.'; $lang['resendpwd'] = 'Send new password for'; $lang['resendpwdmissing'] = 'Sorry, you must fill in all fields.'; $lang['resendpwdnouser'] = 'Sorry, we can\'t find this user in our database.'; +$lang['resendpwdbadauth'] = 'Sorry, this auth code is not valid. Make sure you used the complete confirmation link.'; +$lang['resendpwdconfirm'] = 'A confirmation link has been sent by email.'; $lang['resendpwdsuccess'] = 'Your new password has been sent by email.'; $lang['txt_upload'] = 'Select file to upload'; diff --git a/inc/lang/en/password.txt b/inc/lang/en/password.txt index 45b88cf8a..661d35fca 100644 --- a/inc/lang/en/password.txt +++ b/inc/lang/en/password.txt @@ -1,10 +1,10 @@ -Hi @FULLNAME@!
-
-Here is your userdata for @TITLE@ at @DOKUWIKIURL@
-
-Login : @LOGIN@
-Password : @PASSWORD@
-
---
-This mail was generated by DokuWiki at
-@DOKUWIKIURL@
+Hi @FULLNAME@! + +Here is your userdata for @TITLE@ at @DOKUWIKIURL@ + +Login : @LOGIN@ +Password : @PASSWORD@ + +-- +This mail was generated by DokuWiki at +@DOKUWIKIURL@ diff --git a/inc/lang/en/pwconfirm.txt b/inc/lang/en/pwconfirm.txt new file mode 100644 index 000000000..e91e2ebc5 --- /dev/null +++ b/inc/lang/en/pwconfirm.txt @@ -0,0 +1,15 @@ +Hi @FULLNAME@! + +Someone requested a new password for your @TITLE@ +login at @DOKUWIKIURL@ + +If you did not request a new password then just ignore this email. + +To confirm that the request was really sent by you please use the +following link. + +@CONFIRM@ + +-- +This mail was generated by DokuWiki at +@DOKUWIKIURL@ diff --git a/inc/lang/en/resendpwd.txt b/inc/lang/en/resendpwd.txt index fdc3cdb21..d8b1bf90b 100644 --- a/inc/lang/en/resendpwd.txt +++ b/inc/lang/en/resendpwd.txt @@ -1,5 +1,6 @@ ====== Send new password ====== -Fill in all the information below to get a new password for your account in this wiki. -Your new password will be sent to your registered email address. The user name should be -your wiki user name. +Please enter your user name in the form below to request a new password for your +account in this wiki. A confirmation link will be sent to your registered email +address. + |