Auth.class.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <?php
  2. /*
  3. * DON'T REMOVE THE FOLLOWING LICENSE
  4. * INFORMATION!
  5. * ----------------------------------
  6. * Copyright by
  7. * Dennis Ritz
  8. * Author: Dennis Ritz
  9. * dennis.ritz@gmx.net
  10. * 2007-2008
  11. * ----------------------------------
  12. */
  13. define('AUTH_SESSION', 'AUTH');
  14. define('AUTH_UNDEFINED', 0);
  15. define('AUTH_NOT_LOGGED', -1);
  16. define('AUTH_LOGGED_IN', 1);
  17. define('AUTH_LOGGED_OUT', -2);
  18. define('AUTH_EXPIRED', -3);
  19. define('AUTH_TIMEOUT', -4);
  20. define('AUTH_FAILED', -5);
  21. define('AUTH_ERROR', -6);
  22. define('AUTH_SECURITY', -7);
  23. define('AUTH_CONFIRM_LOGIN',-8);
  24. class Auth
  25. {
  26. private $_status = AUTH_UNDEFINED;
  27. private $_options = array("timeout" => 1800,
  28. "expired" => 0
  29. );
  30. private $_props = array( 'username' => null,
  31. 'password' => null,
  32. 'session' => null,
  33. 'userAgent' => null,
  34. 'ip' => null
  35. );
  36. private $_authSessionsFile = "authSessions.xml";
  37. public $authFile;
  38. protected function __construct(){
  39. $this->authFile = ROOT_DIR."lib/auth.xml";
  40. }
  41. final public function assignUser($p_username,$p_password)
  42. {
  43. /* Empty passwords are allowed. Empty usernames not. */
  44. if ($p_username
  45. && $p_username != '') {
  46. $this->_props['username'] = $p_username;
  47. if ($p_password) {
  48. $this->_props['password'] = $p_password;
  49. }
  50. }
  51. }
  52. final public function getAuth()
  53. {
  54. return $this->getAuthStatus() == AUTH_LOGGED_IN;// && $this->_props['username'] != $this->_default['username'];
  55. }
  56. final public function getAuthStatus()
  57. {
  58. if ($this->_status != AUTH_UNDEFINED)
  59. return $this->_status;
  60. return $this->_processStatus();
  61. }
  62. private function _processStatus()
  63. {
  64. $this->_updateTimeout();
  65. $status = $this->_checkLogin();
  66. return $status;
  67. }
  68. public function login($p_username=null,$p_password=null)
  69. {
  70. $this->_status = AUTH_UNDEFINED;
  71. if(!empty($p_username) && !empty($p_password))
  72. $this->assignUser($p_username,$p_password);
  73. if ($this->_getProp('username') != null) {
  74. $password = $this->_getPassword();
  75. if (isset($password)) {
  76. if (! strcmp($password, md5($this->_getProp('password')))) {
  77. if($this->_confirmLogin() && $this->getAuthStatus() != AUTH_CONFIRM_LOGIN && !$this->_getProp("global")) {
  78. $status = AUTH_CONFIRM_LOGIN;
  79. } else {
  80. $status = AUTH_LOGGED_IN;
  81. }
  82. } else {
  83. $status = AUTH_FAILED;
  84. }
  85. } else {
  86. $status = AUTH_FAILED;
  87. }
  88. } else {
  89. $status = AUTH_NOT_LOGGED;
  90. }
  91. if ($status == AUTH_LOGGED_IN) {
  92. $this->_insertSession();
  93. $_SESSION[AUTH_SESSION] = $this->_getProp('session');
  94. } else if ($status == AUTH_FAILED) {
  95. $this->_logFailure();
  96. unset($_SESSION[AUTH_SESSION]);
  97. } else if ($status == AUTH_CONFIRM_LOGIN) {
  98. $this->_insertConfirmSession();
  99. $_SESSION[AUTH_SESSION] = $this->_getProp('session');
  100. }
  101. return $status;
  102. }
  103. private function _confirmLogin() {
  104. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  105. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  106. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  107. //$sessionsForUsername = $authSessionsXpath->query("/sessions/session/@status[./../@username='".$this->_getProp("username")."' and ./../@status='online' and ./../@ip!='".$this->_getProp("ip")."']");;
  108. $sessionsForUsername = $authSessionsXpath->query("/sessions/session/@status[./../@username='".utf8_to_latin1($this->_getProp("username"))."' and ./../@status='online']");;
  109. if($sessionsForUsername->length > 0) {
  110. return true;
  111. } else {
  112. return false;
  113. }
  114. }
  115. public function logout()
  116. {
  117. if ($this->getAuth()) {
  118. $this->_logout();
  119. $this->_processStatus();
  120. }
  121. return AUTH_LOGGED_OUT;
  122. }
  123. final public function getUsername(){
  124. return $this->_getUsername();
  125. }
  126. final public function isRole($p_role) {
  127. switch ($p_role) {
  128. case "admin": if($this->getUsername() == "master" || $this->getUsername() == "admin") return true;
  129. break;
  130. case "master": if($this->getUsername() == "master") return true;
  131. break;
  132. case "user": return true;
  133. break;
  134. }
  135. return false;
  136. }
  137. final protected function getAllUsernames($p_configFile=""){
  138. return $this->_getAllUsernames($p_configFile);
  139. }
  140. public function getSecurityLevel() {
  141. return $this->_getProp("securityLevel");
  142. }
  143. private function _getProp($property) {
  144. if (isset($this->_props[$property]))
  145. return $this->_props[$property];
  146. $ret = null;
  147. switch ($property) {
  148. case 'userAgent':
  149. global $_SERVER;
  150. $ret = $_SERVER['HTTP_USER_AGENT'];
  151. $ret = substr(stripslashes($ret), 0, 255);
  152. break;
  153. case 'ip':
  154. global $_SERVER;
  155. /* Sending HTTP_X_FORWARDED_FOR? OK, send anything you want,
  156. but it must persist for the whole session. */
  157. $ret = array();
  158. foreach (array('REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR') as $key) {
  159. if (isset($_SERVER[$key]))
  160. $ret[] = $_SERVER[$key];
  161. }
  162. $ret = join(' / ', $ret);
  163. break;
  164. case 'session':
  165. if (isset($_SESSION[AUTH_SESSION])) {
  166. $ret = $_SESSION[AUTH_SESSION];
  167. $ret = intval(stripslashes($ret));
  168. } else {
  169. $ret = '';
  170. }
  171. break;
  172. case 'username':
  173. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  174. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  175. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  176. $sessions = $authSessionsXpath->query("/sessions/session/@username[./../@id='".$this->_getProp('session')."' and ./../@status='online' and ./../@ip='".$this->_getProp('ip')."' and ./../@userAgent='".utf8_to_latin1($this->_getProp('userAgent'))."']");
  177. if($sessions->length > 0) {
  178. $ret = $sessions->item($sessions->length-1)->nodeValue;
  179. } else {
  180. $ret = "";
  181. }
  182. break;
  183. case 'global':
  184. $authDOM = new DOMDocument('1.0', 'utf-8');
  185. $authDOM->load(dirname(__file__)."/".$this->authFile);
  186. $authXpath = new DOMXpath($authDOM);
  187. $global = @$authXpath->query("/auth/users/user/@global[./../@username='".utf8_to_latin1($this->_getProp('username'))."']")->item(0)->nodeValue;
  188. if($global == "true") {
  189. $ret = true;
  190. } else {
  191. $ret = false;
  192. }
  193. break;
  194. case 'securityLevel':
  195. $authDOM = new DOMDocument('1.0', 'utf-8');
  196. $authDOM->load(dirname(__file__)."/".$this->authFile);
  197. $authXpath = new DOMXpath($authDOM);
  198. $securityLevels = $authXpath->query("/auth/users/user/@securityLevel[./../@username='".utf8_to_latin1($this->_getProp('username'))."']");
  199. if($securityLevels->length > 0) {
  200. $ret = $securityLevels->item($securityLevels->length-1)->nodeValue;
  201. } else {
  202. $ret = null;
  203. }
  204. break;
  205. }
  206. if(!empty($ret)) {
  207. $this->_props[$property] = $ret;
  208. }
  209. return $ret;
  210. }
  211. private function _getPassword(){
  212. $MISConfig = new MISConfig();
  213. $authDOM = new DOMDocument('1.0', 'utf-8');
  214. $authDOM->load(dirname(__file__)."/".$this->authFile);
  215. $authXpath = new DOMXpath($authDOM);
  216. $passwords = $authXpath->query("/auth/users/user/@password[(./../@setting='".basename($MISConfig->getConfigFile(),".xml")."' or ./../@setting='') and ./../@username = '".utf8_to_latin1($this->_getProp('username'))."']");
  217. if($passwords->length > 0) {
  218. $password = $passwords->item($passwords->length-1)->nodeValue;
  219. } else {
  220. $password = "";
  221. }
  222. return $password;
  223. }
  224. private function _deleteOldSessions() {
  225. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  226. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  227. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  228. $sessions = $authSessionsXpath->query("/sessions/session[@login < '".(time()-604800)."' and @login != '' and @id!='master']");
  229. if($sessions->length > 0) {
  230. $sessionParent = $sessions->item(0)->parentNode;
  231. foreach($sessions as $session) {
  232. $sessionParent->removeChild($session);
  233. }
  234. }
  235. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  236. }
  237. private function _insertSession(){
  238. $this->_deleteOldSessions();
  239. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  240. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  241. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  242. do {
  243. $id = mt_rand();
  244. $sessions = $authSessionsXpath->query("/sessions/session[@id = '".$id."']");
  245. } while ($sessions->length > 0);
  246. //$sessions = $authSessionsXpath->query("/sessions/session[@status='online' and @username='".$this->_getProp('username')."' and @ip!='".$this->_getProp('ip')."']");
  247. if(!$this->_getProp("global")) {
  248. $sessions = $authSessionsXpath->query("/sessions/session[@status='online' and @username='".utf8_to_latin1($this->_getProp('username'))."']");
  249. if($sessions->length > 0) {
  250. //Set status = 'security'
  251. for($i=0;$i<$sessions->length;$i++) {
  252. $session = $sessions->item($i);
  253. $session->attributes->getNamedItem("status")->nodeValue = "security";
  254. $session->attributes->getNamedItem("logout")->nodeValue = time();
  255. }
  256. }
  257. $sessions = $authSessionsXpath->query("/sessions/session[@status='confirm' and @session='".$this->_getProp("session")."' and @username='".utf8_to_latin1($this->_getProp('username'))."' and @ip='".$this->_getProp('ip')."']");
  258. if($sessions->length > 0) {
  259. //Set status = 'security'
  260. for($i=0;$i<$sessions->length;$i++) {
  261. $session = $sessions->item($i);
  262. $session->attributes->getNamedItem("status")->nodeValue = "online";
  263. $session->attributes->getNamedItem("logout")->nodeValue = time();
  264. }
  265. return;
  266. }
  267. }
  268. $master = $authSessionsXpath->query("/sessions/session[@id = 'master']")->item(0);
  269. $newSession = $master->cloneNode(true);
  270. $newSession->attributes->getNamedItem("id")->nodeValue = $id;
  271. $newSession->attributes->getNamedItem("username")->nodeValue = utf8_to_latin1($this->_getProp('username'));
  272. $newSession->attributes->getNamedItem("password")->nodeValue = "";
  273. $newSession->attributes->getNamedItem("status")->nodeValue = "online";
  274. $newSession->attributes->getNamedItem("login")->nodeValue = time();
  275. $newSession->attributes->getNamedItem("logout")->nodeValue = time();
  276. $newSession->attributes->getNamedItem("ip")->nodeValue = $this->_getProp("ip");
  277. $newSession->attributes->getNamedItem("userAgent")->nodeValue = utf8_to_latin1($this->_getProp("userAgent"));
  278. $master->parentNode->appendChild($newSession);
  279. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  280. $this->_props['session'] = $id;
  281. }
  282. private function _insertConfirmSession(){
  283. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  284. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  285. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  286. do {
  287. $id = mt_rand();
  288. $sessions = $authSessionsXpath->query("/sessions/session[@id = '".$id."']");
  289. } while ($sessions->length > 0);
  290. $master = $authSessionsXpath->query("/sessions/session[@id = 'master']")->item(0);
  291. $newSession = $master->cloneNode(true);
  292. $newSession->attributes->getNamedItem("id")->nodeValue = $id;
  293. $newSession->attributes->getNamedItem("username")->nodeValue = utf8_to_latin1($this->_getProp('username'));
  294. $newSession->attributes->getNamedItem("password")->nodeValue = "";
  295. $newSession->attributes->getNamedItem("status")->nodeValue = "confirm";
  296. $newSession->attributes->getNamedItem("login")->nodeValue = time();
  297. $newSession->attributes->getNamedItem("logout")->nodeValue = time();
  298. $newSession->attributes->getNamedItem("ip")->nodeValue = $this->_getProp("ip");
  299. $newSession->attributes->getNamedItem("userAgent")->nodeValue = utf8_to_latin1($this->_getProp("userAgent"));
  300. $master->parentNode->appendChild($newSession);
  301. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  302. $this->_props['session'] = $id;
  303. }
  304. private function _logFailure() {
  305. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  306. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  307. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  308. $master = $authSessionsXpath->query("/sessions/session[@id = 'master']")->item(0);
  309. $newSession = $master->cloneNode(true);
  310. $newSession->attributes->getNamedItem("id")->nodeValue = $this->_getProp('session');
  311. $newSession->attributes->getNamedItem("username")->nodeValue = utf8_to_latin1($this->_getProp('username'));
  312. $newSession->attributes->getNamedItem("password")->nodeValue = $this->_getProp('password');
  313. $newSession->attributes->getNamedItem("status")->nodeValue = "failed";
  314. $newSession->attributes->getNamedItem("login")->nodeValue = time();
  315. $newSession->attributes->getNamedItem("logout")->nodeValue = time();
  316. $newSession->attributes->getNamedItem("ip")->nodeValue = $this->_getProp("ip");
  317. $newSession->attributes->getNamedItem("userAgent")->nodeValue = utf8_to_latin1($this->_getProp("userAgent"));
  318. $master->parentNode->appendChild($newSession);
  319. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  320. }
  321. private function _updateTimeout() {
  322. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  323. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  324. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  325. if ($this->_options["timeout"] > 0) {
  326. $timeoutTime = time()-$this->_options['timeout'];
  327. $timeoutSessions = $authSessionsXpath->query("/sessions/session[@status = 'online' and @logout < ".$timeoutTime."]");
  328. for($i=0;$i < $timeoutSessions->length;$i++) {
  329. $timeoutSession = $timeoutSessions->item($i);
  330. $timeoutSession->attributes->getNamedItem("status")->nodeValue = "timeout";
  331. }
  332. }
  333. if ($this->_options["expired"] > 0) {
  334. $expiredTime = time()-$this->_options['expired'];
  335. $expiredSessions = $authSessionsXpath->query("/sessions/session[@status = 'online' and @login < ".$timeoutTime."]");
  336. for($i=0;$i < $expiredSessions->length;$i++) {
  337. $expiredSession = $expiredSessions->item($i);
  338. $expiredSession->attributes->getNamedItem("status")->nodeValue = "expired";
  339. }
  340. }
  341. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  342. }
  343. // This method needs ISDN fastfix
  344. private function _logout() {
  345. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  346. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  347. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  348. $sessions = $authSessionsXpath->query("/sessions/session[@status='online' and @id='".$this->_getProp("session")."' and @ip='".$this->_getProp("ip")."' and @userAgent='".utf8_to_latin1($this->_getProp("userAgent"))."']");
  349. if($sessions->length > 0) {
  350. $session = $sessions->item(($sessions->length-1));
  351. $session->attributes->getNamedItem("status")->nodeValue = "logout";
  352. $session->attributes->getNamedItem("logout")->nodeValue = time();
  353. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  354. }
  355. }
  356. // This method needs ISDN fastfix
  357. private function _updateLogin(){
  358. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  359. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  360. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  361. $sessions = $authSessionsXpath->query("/sessions/session[@status = 'online' and @id = '".$this->_getProp('session')."' and @ip = '".$this->_getProp('ip')."' and @userAgent = '".utf8_to_latin1($this->_getProp('userAgent'))."']");
  362. if($sessions->length > 0) {
  363. $session = $sessions->item(($sessions->length-1));
  364. $session->attributes->getNamedItem("logout")->nodeValue = time();
  365. $authSessionsDOM->save(dirname(__file__)."/".$this->_authSessionsFile);
  366. return true;
  367. } else {
  368. return false;
  369. }
  370. }
  371. // This method needs ISDN fastfix
  372. private function _checkLogin(){
  373. if ($this->_updateLogin() == true)
  374. return AUTH_LOGGED_IN;
  375. $authSessionsDOM = new DOMDocument('1.0', 'utf-8');
  376. $authSessionsDOM->load(dirname(__file__)."/".$this->_authSessionsFile);
  377. $authSessionsXpath = new DOMXpath($authSessionsDOM);
  378. $sessions = $authSessionsXpath->query("/sessions/session/@status[./../@id='".$this->_getProp('session')."' and ./../@id!='' and ./../@ip='".$this->_getProp('ip')."' and ./../@userAgent='".utf8_to_latin1($this->_getProp('userAgent'))."']");
  379. if($sessions->length > 0) {
  380. $status = $sessions->item($sessions->length-1)->nodeValue;
  381. } else {
  382. $status = null;
  383. }
  384. if ($status == 'logout') return AUTH_LOGGED_OUT;
  385. if ($status == 'failed') return AUTH_FAILED;
  386. if ($status == 'timeout') return AUTH_TIMEOUT;
  387. if ($status == 'expired') return AUTH_EXPIRED;
  388. if ($status == 'security') return AUTH_SECURITY;
  389. if ($status == 'confirm') return AUTH_CONFIRM_LOGIN;
  390. if ($status == 'online') return AUTH_LOGGED_IN;
  391. return AUTH_NOT_LOGGED;
  392. }
  393. private function _getUsername() {
  394. return $this->_getProp("username");
  395. }
  396. private function _getAllUsernames($p_configFile) {
  397. $MISConfig = new MISConfig();
  398. $authDOM = new DOMDocument('1.0', 'utf-8');
  399. $authDOM->load(dirname(__file__)."/".$this->authFile);
  400. $authXpath = new DOMXpath($authDOM);
  401. if($p_configFile == "") $configFile = $MISConfig->getConfigFile();
  402. else $configFile = $p_configFile;
  403. $usersArr = array();
  404. $usersList = $authXpath->query("/auth/users/user[@setting='".basename($configFile,".xml")."' or @setting='']");
  405. for($i=0;$i<$usersList->length;$i++) {
  406. if($usersList->item($i)->getAttribute('username') == "") continue;
  407. array_push($usersArr,$usersList->item($i)->getAttribute('username'));
  408. }
  409. return $usersArr;
  410. }
  411. public function notice($p_msg) {
  412. Log::notice(__FILE__,__LINE__,$p_msg);
  413. }
  414. public function warning($p_msg) {
  415. Log::warning(__FILE__,__LINE__,$p_mgs);
  416. }
  417. public function error($p_msg) {
  418. Log::error(__FILE__,__LINE__,$p_msg);
  419. }
  420. }
  421. ?>