summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2006-07-14 13:05:48 +0200
committerAndreas Gohr <andi@splitbrain.org>2006-07-14 13:05:48 +0200
commit1d5856cfe64e778c70fece0d08d36f153be16600 (patch)
tree0d13fa843fd2693cd5c9c0a5d97865f5a92cdb1f
parent75e487e9d106f5e0a60b5b66552c332c79637442 (diff)
downloadrpg-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.php2
-rw-r--r--inc/auth.php101
-rw-r--r--inc/html.php4
-rw-r--r--inc/lang/en/lang.php2
-rw-r--r--inc/lang/en/password.txt20
-rw-r--r--inc/lang/en/pwconfirm.txt15
-rw-r--r--inc/lang/en/resendpwd.txt7
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.
+