* */ /* * Includes */ require("lmStates.php"); require("lmConfig.php"); require("lmHandler.php"); require("lmPassword.php"); require("lmTwoFactor.php"); require("lmUtils.php"); /* * Class */ class loginManager{ //constructor /** * building... * @param lmConfig $_config configuration for login Manager * @param lmHandler $_eventHandler handler of events * @param lmPassword $_passwordEngine engine for verifying passwords * @return void */ public function __construct($_config, $_eventHandler, $_passwordEngine, $_twoFactor){ $this->config=$_config; $this->eventHandler=$_eventHandler; $this->passwordEngine=$_passwordEngine; $this->twoFactor=$_twoFactor; return; } //settings private $config; private $eventHandler; private $passwordEngine; private $twoFactor; //frontend functions /** * initialize session and set its lifetime * @return bool */ public function init(){ session_set_cookie_params($this->config->getSessionLifetime()); return session_start(); } /** * prepare for login. Run this on the top of your login page! * @return void */ public function loginPrepare(){ $this->passFailedAttempts(); return; } /** * lets start here! * @param int/string @identifier id or username of user * @param string @password cleartext password from input * @param bool $remember save user fot further use * @return void */ public function login($identifier, $password, $remember=false){ global $lm_force_captcha; if($this->passFailedAttempts()){ //not banned if(isset($lm_force_captcha)){ //check captcha if(!isset($_POST['g-recaptcha-response'])){ $captcha_failed=true; $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); $this->eventHandler->handle(lmStates::CAPTCHA_FAILED); return; } else{ if(!lmUtils::validateCaptcha($this->config->getCaptchaSecretkey(), $_POST['g-recaptcha-response'])){ $captcha_failed=true; $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); $this->eventHandler->handle(lmStates::CAPTCHA_FAILED); return; } } } if(!isset($captcha_failed)){ if($this->config->isRememberEnabled()){ //check if remembering is enabled if($this->isRememberingUser() && $this->twoFactor->secondFactor($this->isRememberingUser())){ //remembering. $this->permitLogin($this->isRememberingUser()); //good to go! return; } } //proceed with normal login if($this->config->getAuthType()==lmStates::AUTH_UNAME){ //username based authentication $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, id, password FROM users WHERE username=:identifier and id<>1"); } else{ $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, id, password FROM users WHERE id=:identifier and id<>1"); } $sql->execute(array(":identifier"=>$identifier)); $res=$sql->fetch(PDO::FETCH_ASSOC); if($res['count']==0){ //user not existing $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); $this->eventHandler->handle(lmStates::LOGIN_FAILED); return; } else{ if($this->passwordEngine->verifyPassword($password, $res['password']) && $this->twoFactor->secondFactor($res['id'])){ if($this->config->isRememberEnabled()){ //remember... if he wants to be insecure if($remember){ $this->rememberUser($res['id']); } } $this->permitLogin($res['id']); //good to go! return; } else{ $this->addLoginHistory($res['id'], lmStates::LOGIN_FAILED); $this->eventHandler->handle(lmStates::LOGIN_FAILED); return; } } } } return; } /** * finish it up! * @return void */ public function logout(){ $_SESSION=array(); session_destroy(); setcookie("lm_login_random", NULL, -1); $this->eventHandler->handle(lmStates::LOGOUT_DONE); return; } /** * just some formal checking * @return bool */ public function validateLogin(){ if(!isset($_SESSION['lm_id'])){ return false; } else{ $sql=$this->config->getPDO()->prepare("SELECT auth_token FROM login_history WHERE user=:id and success=1 ORDER BY id DESC LIMIT 1"); $sql->execute(array(":id"=>$_SESSION['lm_id'])); $res=$sql->fetch(PDO::FETCH_ASSOC); if($res['auth_token']==$this->getSessionKey()){ return true; } else{ return false; } } } /** * do i know you? * @return int */ public function isRememberingUser(){ if(!$this->config->isRememberEnabled()){ return NULL; } if(is_null($this->getRememberKey())){ return NULL; } else{ $sql=$this->config->getPDO()->prepare("SELECT COUNT(id) AS count, user FROM login_remember WHERE remember_token=:token and until>:until"); $sql->execute(array(":token"=>$this->getRememberKey(), ":until"=>date("Y-m-d H:i:s"))); $res=$sql->fetch(PDO::FETCH_ASSOC); if($res['count']!=1){ $this->addLoginHistory(lmStates::NOUSER, lmStates::LOGIN_FAILED); return NULL; } else{ return $res['user']; } } } /** * i don't know you anymore! * @return void */ public function forgetUser(){ $sql=$this->config->getPDO()->prepare("UPDATE login_remember SET until=0 WHERE remember_token=:token"); $sql->execute(array(":token"=>$this->getRememberKey())); setcookie("lm_login_remember", NULL, -1); $this->eventHandler->handle(lmStates::FORGET_DONE); return; } /** * print captcha html code if needed * @param bool $dark use the dark theme, default false * @return void */ public function printCaptcha($dark=false){ if($this->config->isCaptchaEnabled()){ global $lm_force_captcha; if(isset($lm_force_captcha)){ if($dark){ echo "