function validate($user, $pass, $challenge, $response) { parent::validate($user, $pass, $challenge, $response); global $gBitSystem; global $gBitDb; $ret = SERVER_ERROR; if (empty($user)) { $this->mErrors['login'] = '******'; } elseif (empty($pass)) { $this->mErrors['login'] = '******'; } else { $loginVal = strtoupper($user); // case insensitive login $loginCol = ' UPPER(`' . (strpos($user, '@') ? 'email' : 'login') . '`)'; // first verify that the user exists $query = "select `email`, `login`, `user_id`, `user_password` from `" . BIT_DB_PREFIX . "users_users` where " . $gBitDb->convertBinary() . " {$loginCol} = ?"; $result = $gBitDb->query($query, array($loginVal)); if (!$result->numRows()) { $this->mErrors['login'] = '******'; } else { $res = $result->fetchRow(); $userId = $res['user_id']; $user = $res['login']; // TikiWiki 1.8+ uses this bizarro conglomeration of fields to get the hash. this sucks for many reasons $hash = md5(strtolower($user) . $pass . $res['email']); $hash2 = md5($pass); // next verify the password with 2 hashes methods, the old one (pass)) and the new one (login.pass;email) // TODO - this needs cleaning up - wolff_borg if (!$gBitSystem->isFeatureActive('feature_challenge') || empty($response)) { $query = "select `user_id`, `hash` from `" . BIT_DB_PREFIX . "users_users` where " . $gBitDb->convertBinary() . " {$loginCol} = ? and (`hash`=? or `hash`=?)"; if ($row = $gBitDb->getRow($query, array($loginVal, $hash, $hash2))) { // auto-update old hashes with simple and standard md5( password ) $hashUpdate = ''; if ($row['hash'] == $hash) { $hashUpdate = 'hash=?, '; $bindVars[] = $hash2; } $bindVars[] = $gBitSystem->getUTCTime(); $bindVars[] = $userId; $query = "update `" . BIT_DB_PREFIX . "users_users` set {$hashUpdate} `last_login`=`current_login`, `current_login`=? where `user_id`=?"; $result = $gBitDb->query($query, $bindVars); $ret = USER_VALID; } else { $ret = PASSWORD_INCORRECT; $this->mErrors[] = 'Password incorrect'; } } else { // Use challenge-reponse method // Compare pass against md5(user,challenge,hash) $hash = $gBitDb->getOne("select `hash` from `" . BIT_DB_PREFIX . "users_users` where " . $gBitDb->convertBinary() . " {$loginCol} = ?", array($user)); if (!isset($_SESSION["challenge"])) { $this->mErrors[] = 'Invalid challenge'; $ret = PASSWORD_INCORRECT; } //print("pass: $pass user: $user hash: $hash <br/>"); //print("challenge: ".$_SESSION["challenge"]." challenge: $challenge<br/>"); //print("response : $response<br/>"); if ($response == md5(strtolower($user) . $hash . $_SESSION["challenge"])) { $ret = USER_VALID; $this->updateLastLogin($userId); } else { $this->mErrors[] = 'Invalid challenge'; $ret = PASSWORD_INCORRECT; } } } if (!empty($userId)) { $this->mInfo['user_id'] = $userId; } } return $ret; }
function validate($user, $pass, $challenge, $response) { parent::validate($user, $pass, $challenge, $response); global $gBitDb; if (empty($user) or empty($pass)) { return USER_NOT_FOUND; } $this->mInfo["real_name"] = ''; // This needs fixing in the base code - real_name will only exist if a user has been identiied // Use V3, which requires UTF-8: $this->mConfig['version'] = 3; $user_utf8 = utf8_encode($user); if ($this->mConfig['reqcert']) { // Skip the SSL certificate check: // (This assumes PHP is using the OpenLDAP client library.) putenv('LDAPTLS_REQCERT=never'); } if ($this->mConfig['activedirectory']) { $this->mConfig['attributes'] = (array) null; $this->mConfig['userfilter'] = '(objectClass=' . $this->mConfig['useroc'] . ')'; $this->mConfig['groupfilter'] = '(objectClass=' . $this->mConfig['groupoc'] . ')'; $this->mConfig['groupscope'] = $this->mConfig['userscope']; } else { // Using bitweaver groups with LDAP still needs completing so disable for now unset($this->mConfig['group']); } $a = new Auth('LDAP', $this->mConfig, "", false); $a->_loadStorage(); // set up connection to ldap via user details // First, try by username. If that fails, try by email address. $success = $a->storage->fetchData($user_utf8, $pass, false); if ($success == false) { // The user wasn't found. Try again by email address: $this->mConfig['userattrsto'] = $this->mConfig['userattr']; // Keep this for later $this->mConfig['userattr'] = $this->mConfig['email']; // Tell PEAR::Auth() to look at the 'mail' attribute // this needs testing better, should be no need to create second instance of Auth! $a = new Auth('LDAP', $this->mConfig, "", false); $a->_loadStorage(); // set up connection to ldap via user details $success = $a->storage->fetchData($user_utf8, $pass, false); if ($success == false) { $this->mErrors['login'] = isset($a->storage->options['status']) ? $a->storage->options['status'] : 'Not authenticated'; return PASSWORD_INCORRECT; } } // At this point, there was a successful ldap_bind() using the // user's Distinguished Name (DN) and password for login. // The call to ldap_get_attributes() has been saved into $a->getAuthData('attributes') if ($this->mConfig['activedirectory']) { // Active Directory does some things differently - mainly in the returns $attributes = $a->getAuthData(); // Warning: ldap_get_attributes() uses case-sensitive array keys $this->mInfo["login"] = $attributes[$this->mConfig['userattr']]; $this->mInfo["email"] = $attributes[$this->mConfig['email']]; $this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']]; } else { $attributes = $a->getAuthData('attributes'); // Warning: ldap_get_attributes() uses case-sensitive array keys $this->mInfo["login"] = $attributes[$this->mConfig['userattr']][0]; $this->mInfo["email"] = $attributes[$this->mConfig['email']][0]; $this->mInfo["real_name"] = empty($attributes[$this->mConfig['name']][0]) ? $this->mInfo["login"] : $attributes[$this->mConfig['name']][0]; } // Note, the new (or updated) SQL user will be created by the calling BitUser class. return USER_VALID; // Success! }
function validate($user, $pass, $challenge, $response) { parent::validate($user, $pass, $challenge, $response); $mailbox = '{' . $this->mConfig['server']; if ($this->mConfig["ssl"]) { $mailbox .= "/ssl"; if ($this->mConfig["sslvalidate"]) { $mailbox .= "/validate-cert"; } else { $mailbox .= "/novalidate-cert"; } } $mailbox .= ':' . $this->mConfig["port"] . '}INBOX'; $imapauth = @imap_open($mailbox, $user, $pass); if (!$imapauth) { $this->mErrors['login'] = imap_errors(); $ret = USER_NOT_FOUND; } else { $ret = USER_VALID; $this->mInfo["real_name"] = $user; if (empty($this->mConfig["email"])) { $this->mInfo["email"] = $user; } else { $info = array('login' => $user); $replace_func = create_function('$matches', '$info = ' . var_export($info, true) . '; $m = $matches[0]; $m = substr($m,1,strlen($m)-2); if(empty($info[$m])) return ""; return strtolower($info[$m]);'); $this->mInfo["email"] = preg_replace_callback('/%.*?%/', $replace_func, $this->mConfig["email"]); } imap_close($imapauth); } return $ret; }