X-Git-Url: http://git.roojs.org/?p=Pman.Base;a=blobdiff_plain;f=Pman%2FLogin.php;h=d18cdd5dedd40b90148cc697fa5cab418e8b9760;hp=4f64a7328201973f57d7e92e7691458915e18acc;hb=HEAD;hpb=54a9ad02bb5a80e5a70c518090ec54c151d12886 diff --git a/Pman/Login.php b/Pman/Login.php index 4f64a73..d1d1c8e 100644 --- a/Pman/Login.php +++ b/Pman/Login.php @@ -26,6 +26,16 @@ class Pman_Login extends Pman var $masterTemplate = 'login.html'; var $ip_management = false; + + var $event_suffix = ''; + + // for forgot password email + var $authFrom; + var $authKey; + var $person; + var $bcc; + var $rcpts; + function getAuth() // everyone allowed in here.. { @@ -47,7 +57,7 @@ class Pman_Login extends Pman { $this->initErrorHandling(); - //DB_DataObject::DebugLevel(1); + // DB_DataObject::DebugLevel(5); if (!empty($_REQUEST['logout'])) { return $this->logout(); } @@ -78,8 +88,10 @@ class Pman_Login extends Pman if (!empty($_REQUEST['loginPublic'])) { $this->switchPublicUser($_REQUEST['loginPublic']); } - - $this->jerr("INVALID REQUEST"); + if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('/^check_http/', $_SERVER['HTTP_USER_AGENT'])) { + die("server is alive = authFailure"); // should really use heartbeat now.. + } + $this->jerror("NOTICE-INVALID", "INVALID REQUEST"); exit; } @@ -88,12 +100,12 @@ class Pman_Login extends Pman { $ff = class_exists('HTML_FlexyFramework2') ? HTML_FlexyFramework2::get() : HTML_FlexyFramework::get(); - //DB_DAtaObject::debugLevel(1); + //DB_DAtaObject::debugLevel(1); $u = $this->getAuthUser(); //print_r($u); if ($u) { - $this->addEvent('LOGOUT'); + $this->addEvent('LOGOUT'. $this->event_suffix); $e = DB_DataObject::factory('Events'); @@ -129,15 +141,20 @@ class Pman_Login extends Pman $tbl = empty($ff->Pman['authTable']) ? 'core_person' : $ff->Pman['authTable']; $u = DB_DataObject::factory($tbl); - $s = DB_DataObject::Factory('core_setting'); - $oath_require = $s->lookup('core', 'two_factor_authentication_requirement'); + $s = DB_DataObject::factory('core_setting'); + $require_oath_val = 1; + $require_oath = $s->lookup('core', 'two_factor_auth_required'); + if(!empty($require_oath)) { + if($require_oath->val == 0) { + $require_oath_val = 0; + } + } if (!$u->isAuth()) { $this->jok(array( - 'id' => 0, - 'require_oath' => empty($oath_require) || $oath_require->val == 1 ? 1 : 0 - )); - exit; + 'id' => 0 + )); + exit; } //die("got here?"); @@ -210,7 +227,7 @@ class Pman_Login extends Pman } $u->login(); // we might need this later.. - $this->addEvent("SWITCH-USER", false, $au->name . ' TO ' . $u->name); + $this->addEvent("LOGIN-SWITCH-USER". $this->event_suffix, false, $au->name . ' TO ' . $u->name); $this->jok("SWITCH"); } @@ -229,7 +246,7 @@ class Pman_Login extends Pman if(!$u->loginPublic()){ $this->jerr('Switch fail'); } - + $this->jok('OK'); } @@ -247,13 +264,46 @@ class Pman_Login extends Pman if (!empty($_REQUEST['logout'])) { return $this->logout(); } - - if (!empty($_REQUEST['passwordRequest'])) { //|| (strpos($_REQUEST['username'], '@') < 1)) { - - return $this->passwordRequest($_REQUEST['passwordRequest']); - + + if(!empty($_REQUEST['check_owner_company'])) { + $core_company = DB_DataObject::factory('core_company'); + $core_company->comptype = 'OWNER'; + $this->jok($core_company->count()); } + if (!empty($_REQUEST['passwordRequest'])) { //|| (strpos($_REQUEST['username'], '@') < 1)) { + return $this->passwordRequest($_REQUEST['passwordRequest']); + } + + if (!empty($_REQUEST['ResetPassword'])) { + if (empty($_REQUEST['id']) || + empty($_REQUEST['ts']) || + empty($_REQUEST['key']) || + empty($_REQUEST['password1']) || + empty($_REQUEST['password2']) || + ($_REQUEST['password1'] != $_REQUEST['password2']) + ) { + $this->jerr("Invalid request to reset password"); + } + + $this->resetPassword($_REQUEST['id'], $_REQUEST['ts'], $_REQUEST['key'], $_REQUEST['password1'] ); + } + + + if (!empty($_REQUEST['_verifyCheckSum'])) { + if (empty($_REQUEST['id']) || + empty($_REQUEST['ts']) || + empty($_REQUEST['key']) + + ) { + $this->jerr("Invalid request to reset password"); + } + + $this->verifyResetPassword($_REQUEST['id'], $_REQUEST['ts'], $_REQUEST['key']); + $this->jok("Checksum is ok"); + } + + // this is 'classic' change password... if (!empty($_REQUEST['changePassword'])) { return $this->changePassword($_REQUEST); } @@ -271,36 +321,38 @@ class Pman_Login extends Pman if (!empty($ip)) { //DB_DataObject::DebugLevel(1); $e = DB_DataObject::Factory('Events'); - $e->action = 'LOGIN-BAD'; + $e->action = 'LOGIN-BAD'. $this->event_suffix; $e->ipaddr = $ip; $e->whereAdd('event_when > NOW() - INTERVAL 10 MINUTE'); if ($e->count() > 5) { - $this->jerror('LOGIN-RATE', "Login failures are rate limited - please try later"); + $this->jerror('LOGIN-RATE'. $this->event_suffix, "Login failures are rate limited - please try later"); } } - //$u->active = 1; + // this was removed before - not quite sure why. + // when a duplicate login account is created, this stops the old one from interfering.. + $u->active = 1; // empty username = not really a hacking attempt. if (empty($_REQUEST['username'])) { //|| (strpos($_REQUEST['username'], '@') < 1)) { - $this->jerror('LOGIN-EMPTY', 'You typed the wrong Username or Password (0)'); + $this->jerror('LOGIN-EMPTY'. $this->event_suffix, 'You typed the wrong Username or Password (0)'); exit; } $u->authUserName($_REQUEST['username']); if ($u->count() > 1 || !$u->find(true)) { - $this->jerror('LOGIN-BAD','You typed the wrong Username or Password (1)'); + $this->jerror('LOGIN-BAD'. $this->event_suffix,'You typed the wrong Username or Password (1)'); exit; } - if (!$u->active()) { - $this->jerror('LOGIN-BAD','Account disabled'); + if (!$u->active()) { + $this->jerror('LOGIN-BAD'. $this->event_suffix,'Account disabled'); } if(!empty($u->oath_key) && empty($_REQUEST['oath_password'])){ - $this->jerror('LOGIN-BAD','Your account requires Two-Factor Authentication'); + $this->jerror('LOGIN-2FA'. $this->event_suffix,'Your account requires Two-Factor Authentication'); } // check if config allows non-owner passwords. @@ -309,22 +361,25 @@ class Pman_Login extends Pman $ff= HTML_FlexyFramework::get(); if (!empty($ff->Pman['auth_comptype']) && $ff->Pman['auth_comptype'] != $u->company()->comptype) { //print_r($u->company()); - $this->jerror('LOGIN-BADUSER', "Login not permited to outside companies"); // serious failure + $this->jerror('LOGIN-BADUSER'. $this->event_suffix, "Login not permited to outside companies"); // serious failure } // note we trim \x10 -- line break - as it was injected the front end // may have an old bug on safari/chrome that added that character in certian wierd scenarios.. if (!$u->checkPassword(trim($_REQUEST['password'],"\x10"))) { - $this->jerror('LOGIN-BAD', 'You typed the wrong Username or Password (2)'); // - " . htmlspecialchars(print_r($_POST,true))."'"); + $this->jerror('LOGIN-BAD'. $this->event_suffix, 'You typed the wrong Username or Password (2)'); // - " . htmlspecialchars(print_r($_POST,true))."'"); exit; } if( - !empty($u->oath_key) && - !$u->checkTwoFactorAuthentication($_REQUEST['oath_password']) - ){ - $this->jerror('LOGIN-BAD', 'You typed the wrong Username or Password (3)'); + !empty($u->oath_key) && + ( + empty($_REQUEST['oath_password']) || + !$u->checkTwoFactorAuthentication($_REQUEST['oath_password']) + ) + ) { + $this->jerror('LOGIN-BAD'. $this->event_suffix, 'You typed the wrong Username or Password (3)'); exit; } @@ -332,9 +387,18 @@ class Pman_Login extends Pman $u->login(); // we might need this later.. - $this->addEvent("LOGIN", false, session_id()); + $this->addEvent("LOGIN". $this->event_suffix, false, session_id()); + + + if (!empty($_REQUEST['lang'])) { - $u->lang($_REQUEST['lang']); + + if (!empty($ff->languages['avail']) && !in_array($_REQUEST['lang'],$ff->languages['avail'])) { + // ignore. + } else { + + $u->lang($_REQUEST['lang']); + } } // log it.. @@ -371,9 +435,11 @@ class Pman_Login extends Pman // sort out sender. $cm = DB_DataObject::factory('core_email'); if (!$cm->get('name', 'ADMIN_PASSWORD_RESET')) { - $this->jerr("no template ADMIN_PASSWORD_RESET exists - please run importer "); - + $this->jerr("no template Admin password reset (ADMIN_PASSWORD_RESET) exists - please run importer "); } + if (!$cm->active) { + $this->jerr("template for Admin password reset has been disabled"); + } /* $g = DB_DAtaObject::factory('Groups'); @@ -391,12 +457,12 @@ class Pman_Login extends Pman // bcc.. $g = DB_DAtaObject::factory('core_group'); - if (!$g->get('name', 'bcc-email')) { - $this->jerr("no group 'bcc-email' exists in the system"); + if (!$cm->bcc_group_id || !$g->get($cm->bcc_group_id)) { + $this->jerr("BCC for ADMIN_PASSWORD_RESET email has not been set"); } $bcc = $g->members('email'); if (!count($bcc)) { - $this->jerr( "'bcc-email' group does not have any members"); + $this->jerr( "'BCC group for ADMIN_PASSWORD_RESET does not have any members"); } @@ -408,14 +474,19 @@ class Pman_Login extends Pman $this->bcc = $bcc; $this->rcpts = $u->getEmailFrom(); - $ret = $cm->send($this); - //$this->jerr(print_r($r->toData(),true)); - - if (is_object($ret)) { - $this->addEvent('SYSERR',false, $ret->getMessage()); - $this->jerr($ret->getMessage()); - } - $this->addEvent('PASSREQ',$u, $u->email); + + $mailer = $cm->toMailer($this, false); + if (is_a($mailer,'PEAR_Error') ) { + $this->addEvent('SYSERR',false, $mailer->getMessage()); + $this->jerr($mailer->getMessage()); + } + $sent = $mailer->send(); + if (is_a($sent,'PEAR_Error') ) { + $this->addEvent('SYSERR',false, $sent->getMessage()); + $this->jerr($sent->getMessage()); + } + + $this->addEvent('LOGIN-PASSREQ'. $this->event_suffix,$u, $u->email); $uu = clone($u); $uu->no_reset_sent++; $uu->update($u); @@ -423,46 +494,66 @@ class Pman_Login extends Pman } - function changePassword($r) - { - $au = $this->getAuthUser(); + function verifyResetPassword($id,$t, $key) + { + $au = $this->getAuthUser(); + //print_R($au); if ($au) { - $uu = clone($au); - $au->setPassword($r['passwd1']); - $au->update($uu); - $this->addEvent("CHANGEPASS", $au); - $this->jok($au); - } - // not logged in -> need to validate - if (empty($r['passwordReset'])) { - $this->jerr("invalid request"); - } - // same code as reset pasword - - $bits = explode('/', $r['passwordReset']); - //print_R($bits); - - $res= $this->resetPassword(@$bits[0],@$bits[1],@$bits[2]); - - if ($res !== false) { - $this->jerr($res); + $this->jerr( "Already Logged in - no need to use Password Reset"); } - // key is correct.. let's change password... $u = DB_DataObject::factory('core_person'); - //$u->company_id = $this->company->id; - $u->whereAdd('LENGTH(passwd) > 1'); $u->active = 1; - if (!$u->get($bits[0])) { - $this->jerr("invalid id"); // should not happen!!!! + if (!$u->get($id) || !strlen($u->passwd)) { + $this->jerr("Password reset link is not valid (id)"); + } + + // validate key.. + if ($key != $u->genPassKey($t)) { + $this->jerr("Password reset link is not valid (key)"); + } + + if ($t < strtotime("NOW - 1 DAY")) { + $this->jerr("Password reset link has expired"); } + return $u; + + + + } + + + function resetPassword($id,$t, $key, $newpass ) + { + + $u = $this->verifyResetPassword($id,$t,$key); + + $uu = clone($u); - $u->setPassword($r['passwd1']); + $u->no_reset_sent = 0; + if ($newpass != false) { + $u->setPassword($newpass); + } $u->update($uu); - $u->login(); - $this->addEvent("CHANGEPASS", $u); - $this->jok($u); + $this->addEvent("LOGIN-CHANGEPASS". $this->event_suffix, $u); + + $this->jok("Password has been Updated"); + } + + + function changePassword($r) + { + $au = $this->getAuthUser(); + if (!$au) { + $this->jerr("Password change attempted when not logged in"); + } + $uu = clone($au); + $au->setPassword($r['passwd1']); + $au->update($uu); + $this->addEvent("LOGIN-CHANGEPASS". $this->event_suffix, $au); + $this->jok($au); + } function ip_checking() @@ -514,22 +605,22 @@ class Pman_Login extends Pman $core_ip_access->sendXMPP(); - $this->jerr('NEW-IP-ADDRESS', array('ip' => $ip)); + $this->jerror('NEW-IP-ADDRESS', "New IP Address = needs approving", array('ip' => $ip)); return; } if(empty($core_ip_access->status)){ - $this->jerr('PENDING-IP-ADDRESS', array('ip' => $ip)); + $this->jerror('PENDING-IP-ADDRESS', "IP is still pending approval", array('ip' => $ip)); } if($core_ip_access->status == -1){ - $this->jerr('BLOCKED-IP-ADDRESS', array('ip' => $ip)); + $this->jerror('BLOCKED-IP-ADDRESS', "Your IP is blocked", array('ip' => $ip)); return; } if($core_ip_access->status == -2 && strtotime($core_ip_access->expire_dt) < strtotime('NOW')){ - $this->jerr('BLOCKED-IP-ADDRESS', array('ip' => $ip)); + $this->jerror('BLOCKED-IP-ADDRESS', "Your IP is blocked", array('ip' => $ip)); return; }