Auth.class.inc 18 KB

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