[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/ -> auth.php (source)

   1  <?php
   2  /**
   3   * Authentication library
   4   *
   5   * Including this file will automatically try to login
   6   * a user by calling auth_login()
   7   *
   8   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   9   * @author     Andreas Gohr <andi@splitbrain.org>
  10   */
  11  
  12    if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
  13    require_once (DOKU_INC.'inc/common.php');
  14    require_once (DOKU_INC.'inc/io.php');
  15  
  16    // some ACL level defines
  17    define('AUTH_NONE',0);
  18    define('AUTH_READ',1);
  19    define('AUTH_EDIT',2);
  20    define('AUTH_CREATE',4);
  21    define('AUTH_UPLOAD',8);
  22    define('AUTH_DELETE',16);
  23    define('AUTH_ADMIN',255);
  24  
  25    global $conf;
  26  
  27    if($conf['useacl']){
  28      require_once (DOKU_INC.'inc/blowfish.php');
  29      require_once (DOKU_INC.'inc/mail.php');
  30  
  31      global $auth;
  32  
  33      // load the the backend auth functions and instantiate the auth object
  34      if (@file_exists(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php')) {
  35        require_once (DOKU_INC.'inc/auth/basic.class.php');
  36        require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php');
  37  
  38        $auth_class = "auth_".$conf['authtype'];
  39        if (class_exists($auth_class)) {
  40          $auth = new $auth_class();
  41          if ($auth->success == false) {
  42            unset($auth);
  43            msg($lang['authtempfail'], -1);
  44  
  45            // turn acl config setting off for the rest of this page
  46            $conf['useacl'] = 0;
  47          }
  48        } else {
  49          nice_die($lang['authmodfailed']);
  50        }
  51      } else {
  52        nice_die($lang['authmodfailed']);
  53      }
  54    }
  55  
  56    // do the login either by cookie or provided credentials
  57    if($conf['useacl']){
  58      if (!isset($_REQUEST['u'])) $_REQUEST['u'] = '';
  59      if (!isset($_REQUEST['p'])) $_REQUEST['p'] = '';
  60      if (!isset($_REQUEST['r'])) $_REQUEST['r'] = '';
  61  
  62      // if no credentials were given try to use HTTP auth (for SSO)
  63      if(empty($_REQUEST['u']) && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])){
  64        $_REQUEST['u'] = $_SERVER['PHP_AUTH_USER'];
  65        $_REQUEST['p'] = $_SERVER['PHP_AUTH_PW'];
  66      }
  67  
  68      // external trust mechanism in place?
  69      if(!is_null($auth) && $auth->canDo('external')){
  70        $auth->trustExternal($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']);
  71      }else{
  72        auth_login($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']);
  73      }
  74  
  75      //load ACL into a global array
  76      if(is_readable(DOKU_CONF.'acl.auth.php')){
  77        $AUTH_ACL = file(DOKU_CONF.'acl.auth.php');
  78      }else{
  79        $AUTH_ACL = array();
  80      }
  81    }
  82  
  83  /**
  84   * This tries to login the user based on the sent auth credentials
  85   *
  86   * The authentication works like this: if a username was given
  87   * a new login is assumed and user/password are checked. If they
  88   * are correct the password is encrypted with blowfish and stored
  89   * together with the username in a cookie - the same info is stored
  90   * in the session, too. Additonally a browserID is stored in the
  91   * session.
  92   *
  93   * If no username was given the cookie is checked: if the username,
  94   * crypted password and browserID match between session and cookie
  95   * no further testing is done and the user is accepted
  96   *
  97   * If a cookie was found but no session info was availabe the
  98   * blowfish encrypted password from the cookie is decrypted and
  99   * together with username rechecked by calling this function again.
 100   *
 101   * On a successful login $_SERVER[REMOTE_USER] and $USERINFO
 102   * are set.
 103   *
 104   * @author  Andreas Gohr <andi@splitbrain.org>
 105   *
 106   * @param   string  $user    Username
 107   * @param   string  $pass    Cleartext Password
 108   * @param   bool    $sticky  Cookie should not expire
 109   * @return  bool             true on successful auth
 110  */
 111  function auth_login($user,$pass,$sticky=false){
 112    global $USERINFO;
 113    global $conf;
 114    global $lang;
 115    global $auth;
 116    $sticky ? $sticky = true : $sticky = false; //sanity check
 117  
 118    if(!empty($user)){
 119      //usual login
 120      if ($auth->checkPass($user,$pass)){
 121        // make logininfo globally available
 122        $_SERVER['REMOTE_USER'] = $user;
 123        $USERINFO = $auth->getUserData($user); //FIXME move all references to session
 124  
 125        // set cookie
 126        $pass   = PMA_blowfish_encrypt($pass,auth_cookiesalt());
 127        $cookie = base64_encode("$user|$sticky|$pass");
 128        if($sticky) $time = time()+60*60*24*365; //one year
 129        setcookie(DOKU_COOKIE,$cookie,$time,'/');
 130  
 131        // set session
 132        $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
 133        $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass;
 134        $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
 135        $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
 136        return true;
 137      }else{
 138        //invalid credentials - log off
 139        msg($lang['badlogin'],-1);
 140        auth_logoff();
 141        return false;
 142      }
 143    }else{
 144      // read cookie information
 145      $cookie = base64_decode($_COOKIE[DOKU_COOKIE]);
 146      list($user,$sticky,$pass) = split('\|',$cookie,3);
 147      // get session info
 148      $session = $_SESSION[DOKU_COOKIE]['auth'];
 149  
 150      if($user && $pass){
 151        // we got a cookie - see if we can trust it
 152        if(isset($session) &&
 153          ($session['user'] == $user) &&
 154          ($session['pass'] == $pass) &&  //still crypted
 155          ($session['buid'] == auth_browseruid()) ){
 156          // he has session, cookie and browser right - let him in
 157          $_SERVER['REMOTE_USER'] = $user;
 158          $USERINFO = $session['info']; //FIXME move all references to session
 159          return true;
 160        }
 161        // no we don't trust it yet - recheck pass
 162        $pass = PMA_blowfish_decrypt($pass,auth_cookiesalt());
 163        return auth_login($user,$pass,$sticky);
 164      }
 165    }
 166    //just to be sure
 167    auth_logoff();
 168    return false;
 169  }
 170  
 171  /**
 172   * Builds a pseudo UID from browser and IP data
 173   *
 174   * This is neither unique nor unfakable - still it adds some
 175   * security. Using the first part of the IP makes sure
 176   * proxy farms like AOLs are stil okay.
 177   *
 178   * @author  Andreas Gohr <andi@splitbrain.org>
 179   *
 180   * @return  string  a MD5 sum of various browser headers
 181   */
 182  function auth_browseruid(){
 183    $uid  = '';
 184    $uid .= $_SERVER['HTTP_USER_AGENT'];
 185    $uid .= $_SERVER['HTTP_ACCEPT_ENCODING'];
 186    $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
 187    $uid .= $_SERVER['HTTP_ACCEPT_CHARSET'];
 188    $uid .= substr($_SERVER['REMOTE_ADDR'],0,strpos($_SERVER['REMOTE_ADDR'],'.'));
 189    return md5($uid);
 190  }
 191  
 192  /**
 193   * Creates a random key to encrypt the password in cookies
 194   *
 195   * This function tries to read the password for encrypting
 196   * cookies from $conf['metadir'].'/_htcookiesalt'
 197   * if no such file is found a random key is created and
 198   * and stored in this file.
 199   *
 200   * @author  Andreas Gohr <andi@splitbrain.org>
 201   *
 202   * @return  string
 203   */
 204  function auth_cookiesalt(){
 205    global $conf;
 206    $file = $conf['metadir'].'/_htcookiesalt';
 207    $salt = io_readFile($file);
 208    if(empty($salt)){
 209      $salt = uniqid(rand(),true);
 210      io_saveFile($file,$salt);
 211    }
 212    return $salt;
 213  }
 214  
 215  /**
 216   * This clears all authenticationdata and thus log the user
 217   * off
 218   *
 219   * @author  Andreas Gohr <andi@splitbrain.org>
 220   */
 221  function auth_logoff(){
 222    global $conf;
 223    global $USERINFO;
 224    global $INFO, $ID;
 225    global $auth;
 226  
 227    if(isset($_SESSION[DOKU_COOKIE]['auth']['user']))
 228      unset($_SESSION[DOKU_COOKIE]['auth']['user']);
 229    if(isset($_SESSION[DOKU_COOKIE]['auth']['pass']))
 230      unset($_SESSION[DOKU_COOKIE]['auth']['pass']);
 231    if(isset($_SESSION[DOKU_COOKIE]['auth']['info']))
 232      unset($_SESSION[DOKU_COOKIE]['auth']['info']);
 233    if(isset($_SERVER['REMOTE_USER']))
 234      unset($_SERVER['REMOTE_USER']);
 235    $USERINFO=null; //FIXME
 236    setcookie(DOKU_COOKIE,'',time()-600000,'/');
 237  
 238    if($auth && $auth->canDo('logoff')){
 239      $auth->logOff();
 240    }
 241  }
 242  
 243  /**
 244   * Convinience function for auth_aclcheck()
 245   *
 246   * This checks the permissions for the current user
 247   *
 248   * @author  Andreas Gohr <andi@splitbrain.org>
 249   *
 250   * @param  string  $id  page ID
 251   * @return int          permission level
 252   */
 253  function auth_quickaclcheck($id){
 254    global $conf;
 255    global $USERINFO;
 256    # if no ACL is used always return upload rights
 257    if(!$conf['useacl']) return AUTH_UPLOAD;
 258    return auth_aclcheck($id,$_SERVER['REMOTE_USER'],$USERINFO['grps']);
 259  }
 260  
 261  /**
 262   * Returns the maximum rights a user has for
 263   * the given ID or its namespace
 264   *
 265   * @author  Andreas Gohr <andi@splitbrain.org>
 266   *
 267   * @param  string  $id     page ID
 268   * @param  string  $user   Username
 269   * @param  array   $groups Array of groups the user is in
 270   * @return int             permission level
 271   */
 272  function auth_aclcheck($id,$user,$groups){
 273    global $conf;
 274    global $AUTH_ACL;
 275  
 276    # if no ACL is used always return upload rights
 277    if(!$conf['useacl']) return AUTH_UPLOAD;
 278  
 279    $user = auth_nameencode($user);
 280  
 281    //if user is superuser return 255 (acl_admin)
 282    if(auth_nameencode($conf['superuser']) == $user) { return AUTH_ADMIN; }
 283  
 284    //make sure groups is an array
 285    if(!is_array($groups)) $groups = array();
 286  
 287    //prepend groups with @ and nameencode
 288    $cnt = count($groups);
 289    for($i=0; $i<$cnt; $i++){
 290      $groups[$i] = '@'.auth_nameencode($groups[$i]);
 291    }
 292    //if user is in superuser group return 255 (acl_admin)
 293    if(in_array(auth_nameencode($conf['superuser'],true), $groups)) { return AUTH_ADMIN; }
 294  
 295    $ns    = getNS($id);
 296    $perm  = -1;
 297  
 298    if($user){
 299      //add ALL group
 300      $groups[] = '@ALL';
 301      //add User
 302      $groups[] = $user;
 303      //build regexp
 304      $regexp   = join('|',$groups);
 305    }else{
 306      $regexp = '@ALL';
 307    }
 308  
 309    //check exact match first
 310    $matches = preg_grep('/^'.preg_quote($id,'/').'\s+('.$regexp.')\s+/',$AUTH_ACL);
 311    if(count($matches)){
 312      foreach($matches as $match){
 313        $match = preg_replace('/#.*$/','',$match); //ignore comments
 314        $acl   = preg_split('/\s+/',$match);
 315        if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
 316        if($acl[2] > $perm){
 317          $perm = $acl[2];
 318        }
 319      }
 320      if($perm > -1){
 321        //we had a match - return it
 322        return $perm;
 323      }
 324    }
 325  
 326    //still here? do the namespace checks
 327    if($ns){
 328      $path = $ns.':\*';
 329    }else{
 330      $path = '\*'; //root document
 331    }
 332  
 333    do{
 334      $matches = preg_grep('/^'.$path.'\s+('.$regexp.')\s+/',$AUTH_ACL);
 335      if(count($matches)){
 336        foreach($matches as $match){
 337          $match = preg_replace('/#.*$/','',$match); //ignore comments
 338          $acl   = preg_split('/\s+/',$match);
 339          if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
 340          if($acl[2] > $perm){
 341            $perm = $acl[2];
 342          }
 343        }
 344        //we had a match - return it
 345        return $perm;
 346      }
 347  
 348      //get next higher namespace
 349      $ns   = getNS($ns);
 350  
 351      if($path != '\*'){
 352        $path = $ns.':\*';
 353        if($path == ':\*') $path = '\*';
 354      }else{
 355        //we did this already
 356        //looks like there is something wrong with the ACL
 357        //break here
 358        msg('No ACL setup yet! Denying access to everyone.');
 359        return AUTH_NONE;
 360      }
 361    }while(1); //this should never loop endless
 362  
 363    //still here? return no permissions
 364    return AUTH_NONE;
 365  }
 366  
 367  /**
 368   * Encode ASCII special chars
 369   *
 370   * Some auth backends allow special chars in their user and groupnames
 371   * The special chars are encoded with this function. Only ASCII chars
 372   * are encoded UTF-8 multibyte are left as is (different from usual
 373   * urlencoding!).
 374   *
 375   * Decoding can be done with rawurldecode
 376   *
 377   * @author Andreas Gohr <gohr@cosmocode.de>
 378   * @see rawurldecode()
 379   */
 380  function auth_nameencode($name,$skip_group=false){
 381    global $cache_authname;
 382    $cache =& $cache_authname;
 383  
 384    if (!isset($cache[$name][$skip_group])) {
 385      if($skip_group && $name{0} =='@'){
 386        $cache[$name][$skip_group] = '@'.preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e',
 387                                                      "'%'.dechex(ord('\\1'))",substr($name,1));
 388      }else{
 389        $cache[$name][$skip_group] = preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e',
 390                                                  "'%'.dechex(ord('\\1'))",$name);
 391      }
 392    }
 393  
 394    return $cache[$name][$skip_group];
 395  }
 396  
 397  /**
 398   * Create a pronouncable password
 399   *
 400   * @author  Andreas Gohr <andi@splitbrain.org>
 401   * @link    http://www.phpbuilder.com/annotate/message.php3?id=1014451
 402   *
 403   * @return string  pronouncable password
 404   */
 405  function auth_pwgen(){
 406    $pw = '';
 407    $c  = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones
 408    $v  = 'aeiou';              //vowels
 409    $a  = $c.$v;                //both
 410  
 411    //use two syllables...
 412    for($i=0;$i < 2; $i++){
 413      $pw .= $c[rand(0, strlen($c)-1)];
 414      $pw .= $v[rand(0, strlen($v)-1)];
 415      $pw .= $a[rand(0, strlen($a)-1)];
 416    }
 417    //... and add a nice number
 418    $pw .= rand(10,99);
 419  
 420    return $pw;
 421  }
 422  
 423  /**
 424   * Sends a password to the given user
 425   *
 426   * @author  Andreas Gohr <andi@splitbrain.org>
 427   *
 428   * @return bool  true on success
 429   */
 430  function auth_sendPassword($user,$password){
 431    global $conf;
 432    global $lang;
 433    global $auth;
 434  
 435    $hdrs  = '';
 436    $userinfo = $auth->getUserData($user);
 437  
 438    if(!$userinfo['mail']) return false;
 439  
 440    $text = rawLocale('password');
 441    $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
 442    $text = str_replace('@FULLNAME@',$userinfo['name'],$text);
 443    $text = str_replace('@LOGIN@',$user,$text);
 444    $text = str_replace('@PASSWORD@',$password,$text);
 445    $text = str_replace('@TITLE@',$conf['title'],$text);
 446  
 447    return mail_send($userinfo['name'].' <'.$userinfo['mail'].'>',
 448                     $lang['regpwmail'],
 449                     $text,
 450                     $conf['mailfrom']);
 451  }
 452  
 453  /**
 454   * Register a new user
 455   *
 456   * This registers a new user - Data is read directly from $_POST
 457   *
 458   * @author  Andreas Gohr <andi@splitbrain.org>
 459   *
 460   * @return bool  true on success, false on any error
 461   */
 462  function register(){
 463    global $lang;
 464    global $conf;
 465    global $auth;
 466  
 467    if(!$_POST['save']) return false;
 468    if(!$auth->canDo('addUser')) return false;
 469  
 470    //clean username
 471    $_POST['login'] = preg_replace('/.*:/','',$_POST['login']);
 472    $_POST['login'] = cleanID($_POST['login']);
 473    //clean fullname and email
 474    $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname']));
 475    $_POST['email']    = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email']));
 476  
 477    if( empty($_POST['login']) ||
 478        empty($_POST['fullname']) ||
 479        empty($_POST['email']) ){
 480      msg($lang['regmissing'],-1);
 481      return false;
 482    }
 483  
 484    if ($conf['autopasswd']) {
 485      $pass = auth_pwgen();                // automatically generate password
 486    } elseif (empty($_POST['pass']) ||
 487              empty($_POST['passchk'])) {
 488      msg($lang['regmissing'], -1);        // complain about missing passwords
 489      return false;
 490    } elseif ($_POST['pass'] != $_POST['passchk']) {
 491      msg($lang['regbadpass'], -1);      // complain about misspelled passwords
 492      return false;
 493    } else {
 494      $pass = $_POST['pass'];              // accept checked and valid password
 495    }
 496  
 497    //check mail
 498    if(!mail_isvalid($_POST['email'])){
 499      msg($lang['regbadmail'],-1);
 500      return false;
 501    }
 502  
 503    //okay try to create the user
 504    if(!$auth->createUser($_POST['login'],$pass,$_POST['fullname'],$_POST['email'])){
 505      msg($lang['reguexists'],-1);
 506      return false;
 507    }
 508  
 509    // create substitutions for use in notification email
 510    $substitutions = array(
 511      'NEWUSER' => $_POST['login'],
 512      'NEWNAME' => $_POST['fullname'],
 513      'NEWEMAIL' => $_POST['email'],
 514    );
 515  
 516    if (!$conf['autopasswd']) {
 517      msg($lang['regsuccess2'],1);
 518      notify('', 'register', '', $_POST['login'], false, $substitutions);
 519      return true;
 520    }
 521  
 522    // autogenerated password? then send him the password
 523    if (auth_sendPassword($_POST['login'],$pass)){
 524      msg($lang['regsuccess'],1);
 525      notify('', 'register', '', $_POST['login'], false, $substitutions);
 526      return true;
 527    }else{
 528      msg($lang['regmailfail'],-1);
 529      return false;
 530    }
 531  }
 532  
 533  /**
 534   * Update user profile
 535   *
 536   * @author    Christopher Smith <chris@jalakai.co.uk>
 537   */
 538  function updateprofile() {
 539    global $conf;
 540    global $INFO;
 541    global $lang;
 542    global $auth;
 543  
 544    if(empty($_POST['save'])) return false;
 545  
 546    // should not be able to get here without Profile being possible...
 547    if(!$auth->canDo('Profile')) {
 548      msg($lang['profna'],-1);
 549      return false;
 550    }
 551  
 552    if ($_POST['newpass'] != $_POST['passchk']) {
 553      msg($lang['regbadpass'], -1);      // complain about misspelled passwords
 554      return false;
 555    }
 556  
 557    //clean fullname and email
 558    $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname']));
 559    $_POST['email']    = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email']));
 560  
 561    if (empty($_POST['fullname']) || empty($_POST['email'])) {
 562      msg($lang['profnoempty'],-1);
 563      return false;
 564    }
 565  
 566    if (!mail_isvalid($_POST['email'])){
 567      msg($lang['regbadmail'],-1);
 568      return false;
 569    }
 570  
 571    if ($_POST['fullname'] != $INFO['userinfo']['name']) $changes['name'] = $_POST['fullname'];
 572    if ($_POST['email']    != $INFO['userinfo']['mail']) $changes['mail'] = $_POST['email'];
 573    if (!empty($_POST['newpass']))  $changes['pass'] = $_POST['newpass'];
 574  
 575    if (!count($changes)) {
 576      msg($lang['profnochange'], -1);
 577      return false;
 578    }
 579  
 580    if ($conf['profileconfirm']) {
 581        if (!auth_verifyPassword($_POST['oldpass'],$INFO['userinfo']['pass'])) {
 582        msg($lang['badlogin'],-1);
 583        return false;
 584      }
 585    }
 586  
 587    return $auth->modifyUser($_SERVER['REMOTE_USER'], $changes);
 588  }
 589  
 590  /**
 591   * Send a  new password
 592   *
 593   * This function handles both phases of the password reset:
 594   *
 595   *   - handling the first request of password reset
 596   *   - validating the password reset auth token
 597   *
 598   * @author Benoit Chesneau <benoit@bchesneau.info>
 599   * @author Chris Smith <chris@jalakai.co.uk>
 600   * @author Andreas Gohr <andi@splitbrain.org>
 601   *
 602   * @return bool true on success, false on any error
 603  */
 604  function act_resendpwd(){
 605      global $lang;
 606      global $conf;
 607      global $auth;
 608  
 609      if(!actionOK('resendpwd')) return false;
 610  
 611      // should not be able to get here without modPass being possible...
 612      if(!$auth->canDo('modPass')) {
 613          msg($lang['resendna'],-1);
 614          return false;
 615      }
 616  
 617      $token = preg_replace('/[^a-f0-9]+/','',$_REQUEST['pwauth']);
 618  
 619      if($token){
 620          // we're in token phase
 621  
 622          $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth';
 623          if(!@file_exists($tfile)){
 624              msg($lang['resendpwdbadauth'],-1);
 625              return false;
 626          }
 627          $user = io_readfile($tfile);
 628          @unlink($tfile);
 629          $userinfo = $auth->getUserData($user);
 630          if(!$userinfo['mail']) {
 631              msg($lang['resendpwdnouser'], -1);
 632              return false;
 633          }
 634  
 635          $pass = auth_pwgen();
 636          if (!$auth->modifyUser($user,array('pass' => $pass))) {
 637              msg('error modifying user data',-1);
 638              return false;
 639          }
 640  
 641          if (auth_sendPassword($user,$pass)) {
 642              msg($lang['resendpwdsuccess'],1);
 643          } else {
 644              msg($lang['regmailfail'],-1);
 645          }
 646          return true;
 647  
 648      } else {
 649          // we're in request phase
 650  
 651          if(!$_POST['save']) return false;
 652  
 653          if (empty($_POST['login'])) {
 654              msg($lang['resendpwdmissing'], -1);
 655              return false;
 656          } else {
 657              $_POST['login'] = preg_replace('/.*:/','',$_POST['login']);
 658              $user = cleanID($_POST['login']);
 659          }
 660  
 661          $userinfo = $auth->getUserData($user);
 662          if(!$userinfo['mail']) {
 663              msg($lang['resendpwdnouser'], -1);
 664              return false;
 665          }
 666  
 667          // generate auth token
 668          $token = md5(auth_cookiesalt().$user); //secret but user based
 669          $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth';
 670          $url = wl('',array('do'=>'resendpwd','pwauth'=>$token),true,'&');
 671  
 672          io_saveFile($tfile,$user);
 673  
 674          $text = rawLocale('pwconfirm');
 675          $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
 676          $text = str_replace('@FULLNAME@',$userinfo['name'],$text);
 677          $text = str_replace('@LOGIN@',$user,$text);
 678          $text = str_replace('@TITLE@',$conf['title'],$text);
 679          $text = str_replace('@CONFIRM@',$url,$text);
 680  
 681          if(mail_send($userinfo['name'].' <'.$userinfo['mail'].'>',
 682                       $lang['regpwmail'],
 683                       $text,
 684                       $conf['mailfrom'])){
 685              msg($lang['resendpwdconfirm'],1);
 686          }else{
 687              msg($lang['regmailfail'],-1);
 688          }
 689          return true;
 690      }
 691  
 692      return false; // never reached
 693  }
 694  
 695  /**
 696   * Uses a regular expresion to check if a given mail address is valid
 697   *
 698   * May not be completly RFC conform!
 699   *
 700   * @link    http://www.webmasterworld.com/forum88/135.htm
 701   *
 702   * @param   string $email the address to check
 703   * @return  bool          true if address is valid
 704   */
 705  function isvalidemail($email){
 706    return eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$", $email);
 707  }
 708  
 709  /**
 710   * Encrypts a password using the given method and salt
 711   *
 712   * If the selected method needs a salt and none was given, a random one
 713   * is chosen.
 714   *
 715   * The following methods are understood:
 716   *
 717   *   smd5  - Salted MD5 hashing
 718   *   md5   - Simple MD5 hashing
 719   *   sha1  - SHA1 hashing
 720   *   ssha  - Salted SHA1 hashing
 721   *   crypt - Unix crypt
 722   *   mysql - MySQL password (old method)
 723   *   my411 - MySQL 4.1.1 password
 724   *
 725   * @author  Andreas Gohr <andi@splitbrain.org>
 726   * @return  string  The crypted password
 727   */
 728  function auth_cryptPassword($clear,$method='',$salt=''){
 729    global $conf;
 730    if(empty($method)) $method = $conf['passcrypt'];
 731  
 732    //prepare a salt
 733    if(empty($salt)) $salt = md5(uniqid(rand(), true));
 734  
 735    switch(strtolower($method)){
 736      case 'smd5':
 737          return crypt($clear,'$1$'.substr($salt,0,8).'$');
 738      case 'md5':
 739        return md5($clear);
 740      case 'sha1':
 741        return sha1($clear);
 742      case 'ssha':
 743        $salt=substr($salt,0,4);
 744        return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt);
 745      case 'crypt':
 746        return crypt($clear,substr($salt,0,2));
 747      case 'mysql':
 748        //from http://www.php.net/mysql comment by <soren at byu dot edu>
 749        $nr=0x50305735;
 750        $nr2=0x12345671;
 751        $add=7;
 752        $charArr = preg_split("//", $clear);
 753        foreach ($charArr as $char) {
 754          if (($char == '') || ($char == ' ') || ($char == '\t')) continue;
 755          $charVal = ord($char);
 756          $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8);
 757          $nr2 += ($nr2 << 8) ^ $nr;
 758          $add += $charVal;
 759        }
 760        return sprintf("%08x%08x", ($nr & 0x7fffffff), ($nr2 & 0x7fffffff));
 761      case 'my411':
 762        return '*'.sha1(pack("H*", sha1($clear)));
 763      default:
 764        msg("Unsupported crypt method $method",-1);
 765    }
 766  }
 767  
 768  /**
 769   * Verifies a cleartext password against a crypted hash
 770   *
 771   * The method and salt used for the crypted hash is determined automatically
 772   * then the clear text password is crypted using the same method. If both hashs
 773   * match true is is returned else false
 774   *
 775   * @author  Andreas Gohr <andi@splitbrain.org>
 776   * @return  bool
 777   */
 778  function auth_verifyPassword($clear,$crypt){
 779    $method='';
 780    $salt='';
 781  
 782    //determine the used method and salt
 783    $len = strlen($crypt);
 784    if(substr($crypt,0,3) == '$1$'){
 785      $method = 'smd5';
 786      $salt   = substr($crypt,3,8);
 787    }elseif(substr($crypt,0,6) == '{SSHA}'){
 788      $method = 'ssha';
 789      $salt   = substr(base64_decode(substr($crypt, 6)),20);
 790    }elseif($len == 32){
 791      $method = 'md5';
 792    }elseif($len == 40){
 793      $method = 'sha1';
 794    }elseif($len == 16){
 795      $method = 'mysql';
 796    }elseif($len == 41 && $crypt[0] == '*'){
 797      $method = 'my411';
 798    }else{
 799      $method = 'crypt';
 800      $salt   = substr($crypt,0,2);
 801    }
 802  
 803    //crypt and compare
 804    if(auth_cryptPassword($clear,$method,$salt) === $crypt){
 805      return true;
 806    }
 807    return false;
 808  }
 809  
 810  //Setup VIM: ex: et ts=2 enc=utf-8 :


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7