1<?php 2/* 3 * e107 website system 4 * 5 * Copyright (C) 2008-2016 e107 Inc (e107.org) 6 * Released under the terms and conditions of the 7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) 8 * 9 * Administration Area Authorization 10 * 11 * $Source: /cvs_backup/e107_0.8/e107_admin/auth.php,v $ 12 * $Revision$ 13 * $Date$ 14 * $Author$ 15 */ 16 17if (!defined('e107_INIT')) 18{ 19 exit; 20} 21 22 23e107::getDebug()->logTime('(Start auth.php)'); 24 25define('e_CAPTCHA_FONTCOLOR','#F9A533'); 26 27 28 29 30// Required for a clean v1.x -> v2 upgrade. 31$core = e107::getConfig('core'); 32 33if($core->get('admintheme') != 'bootstrap3') 34{ 35 $core->update('admintheme','bootstrap3'); 36 $core->update('adminstyle','infopanel'); 37 $core->update('admincss','admin_dark.css'); 38 $core->set('e_jslib_core',array('prototype' => 'none', 'jquery'=> 'auto')); 39 $core->save(); 40 e107::getRedirect()->redirect(e_SELF); 41} 42 43$admincss = trim($core->get('admincss')); 44if(empty($admincss) || $admincss === 'style.css'|| $admincss === 'admin_dark.css' || $admincss === 'admin_light.css') 45{ 46 $core->update('admincss','css/bootstrap-dark.min.css'); 47 $core->save(false,true); 48 e107::getRedirect()->redirect(e_SELF); 49} 50 51// Check Admin-Perms for current language and redirect if necessary. 52if(USER && !getperms('0') && vartrue($pref['multilanguage']) && !getperms(e_LANGUAGE) && empty($_E107['no_language_perm_check'])) 53{ 54 $lng = e107::getLanguage(); 55 56 $tmp = explode(".",ADMINPERMS); 57 foreach($tmp as $ln) 58 { 59 if(strlen($ln) < 3) // not a language perm. 60 { 61 continue; 62 } 63 64 if($lng->isValid($ln)) 65 { 66 $redirect = deftrue("MULTILANG_SUBDOMAIN") ? $lng->subdomainUrl($ln) : e_SELF."?elan=".$ln; 67 // echo "redirect to: ".$redirect; 68 e107::getRedirect()->go($redirect); 69 // break; 70 } 71 } 72} 73 74 75/* done in class2 76 @include_once(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_admin.php"); 77 @include_once(e_LANGUAGEDIR."English/admin/lan_admin.php"); 78 */ 79if (ADMIN) 80{ 81 define('ADMIN_PAGE', true); 82 //don't include it if it'a an AJAX call or not wanted 83 if (!e_AJAX_REQUEST && !defset('e_NOHEADER')) 84 { 85 // XXX LOGIN AS Temporary solution, we need something smarter, e.g. reserved message stack 'admin' which will be always printed 86 // inside admin area 87 if(e107::getUser()->getSessionDataAs()) 88 { 89 $asuser = e107::getSystemUser(e107::getUser()->getSessionDataAs(), false); 90 91 $lanVars = array ('x' => ($asuser->getId() ? $asuser->getName().' ('.$asuser->getValue('email').')' : 'unknown')) ; 92 e107::getMessage()->addInfo($tp->lanVars(ADLAN_164, $lanVars).' <a href="'.e_ADMIN_ABS.'users.php?mode=main&action=logoutas">['.LAN_LOGOUT.']</a>'); 93 94 } 95 // NEW, legacy 3rd party code fix, header called inside the footer o.O 96 if(deftrue('e_ADMIN_UI')) 97 { 98 // boot.php already loaded 99 require_once (e_ADMIN."header.php"); 100 } 101 else 102 { 103 // boot.php is included in admin dispatcher constructor, so do it only for legacy code 104 require_once(e_ADMIN.'boot.php'); 105 } 106 } 107 108 /* 109 * FIXME - missing $style for tablerender 110 * The Solution: parse_admin() without sending it to the browser if it's an ajax call 111 * The Problem: doubled render time for the ajax called page!!! 112 */ 113} 114else 115{ 116 //login via AJAX call is not allowed 117 if (e_AJAX_REQUEST) 118 { 119 require_once (e_HANDLER.'js_helper.php'); 120 e_jshelper::sendAjaxError(403, ADLAN_86, ADLAN_87, true); 121 } 122 123 require_once(e_ADMIN.'boot.php'); 124 125 $sec_img = e107::getSecureImg(); 126 127 $use_imagecode = (vartrue($pref['admincode']) && extension_loaded("gd")); 128 129 if ($_POST['authsubmit']) 130 { 131 $obj = new auth; 132 133 if ($use_imagecode) 134 { 135 if ($sec_img->invalidCode($_POST['rand_num'], $_POST['code_verify'])) 136 { 137 e107::getRedirect()->redirect('admin.php?failed'); 138 exit; 139 // echo "<script type='text/javascript'>document.location.href='../index.php'</script>\n"; 140 // header("location: ../index.php"); 141 // exit; 142 } 143 } 144 145 // require_once (e_HANDLER.'user_handler.php'); 146 /** @var array $row */ 147 $row = $authresult = $obj->authcheck($_POST['authname'], $_POST['authpass'], varset($_POST['hashchallenge'], '')); 148 149 if ($row[0] == "authfail") 150 { 151 $admin_log->e_log_event(4, __FILE__."|".__FUNCTION__."@".__LINE__, "LOGIN", LAN_ROLL_LOG_11, "U: ".$tp->toDB($_POST['authname']), FALSE, LOG_TO_ROLLING); 152 echo "<script type='text/javascript'>document.location.href='../index.php'</script>\n"; 153 154 e107::getRedirect()->redirect('admin.php?failed'); 155 exit; 156 } 157 else 158 { 159 160 $reHashedPass = e107::getUserSession()->rehashPassword($row,$_POST['authpass']); 161 if($reHashedPass !==false) 162 { 163 e107::getLog()->add('ADMINPW_02', '', E_LOG_INFORMATIVE, '', LOG_TO_ADMIN, $row); 164 $row['user_password'] = $reHashedPass; 165 } 166 167 $cookieval = $row['user_id'].".".md5($row['user_password']); 168 169 // $sql->db_Select("user", "*", "user_name='".$tp -> toDB($_POST['authname'])."'"); 170 // list($user_id, $user_name, $userpass) = $sql->db_Fetch(); 171 172 // Calculate class membership - needed for a couple of things 173 // Problem is that USERCLASS_LIST just contains 'guest' and 'everyone' at this point 174 $class_list = explode(',', $row['user_class']); 175 if ($row['user_admin'] && strlen($row['user_perms'])) 176 { 177 $class_list[] = e_UC_ADMIN; 178 if (strpos($row['user_perms'], '0') === 0) 179 { 180 $class_list[] = e_UC_MAINADMIN; 181 } 182 } 183 $class_list[] = e_UC_MEMBER; 184 $class_list[] = e_UC_PUBLIC; 185 186 187 if (in_array(varset($pref['user_audit_class'], ''), $class_list)) 188 { 189 e107::getAdminLog()->user_audit(USER_AUDIT_LOGIN, 'Login via admin page', $row['user_id'], $row['user_name']); 190 } 191 192 $edata_li = array("user_id"=>$row['user_id'], "user_name"=>$row['user_name'], 'class_list'=>implode(',', $class_list), 'user_admin'=> $row['user_admin']); 193 194 // Fix - set cookie before login trigger 195 $sessionLife = (int) e107::getPref('session_lifetime', ( 3600 * 24 * 30)); // default 1 month. 196 197 if($sessionLife > 0) 198 { 199 $sessionLife = time() + $sessionLife; 200 } 201 202 session_set(e_COOKIE, $cookieval, $sessionLife); 203 204 unset($sessionLife,$cookieval); 205 206 // --- 207 208 e107::getEvent()->trigger("login", $edata_li); 209 210 211 212 e107::getRedirect()->redirect(e_ADMIN_ABS.'admin.php'); 213 //echo "<script type='text/javascript'>document.location.href='admin.php'</script>\n"; 214 } 215 } 216 217 $e_sub_cat = 'logout'; 218 if (ADMIN == FALSE) 219 { 220 define("e_IFRAME",TRUE); 221 } 222 if (!defset('NO_HEADER')) 223 require_once (e_ADMIN."header.php"); 224 225 if (ADMIN == FALSE) 226 { 227 // Needs help from Deso, Vesko and Stoev! :-) 228 229 e107::css('inline'," 230 231 body { text-align: left; font-size:15px; line-height:1.5em; font-weight:normal; 232 font-family:Arial, Helvetica, sans-serif; background-attachment: scroll; 233 /* background-color: rgb(47, 47, 47); color: rgb(198, 198, 198); */ 234 235 background-repeat: no-repeat; background-size: auto auto 236 } 237 a { color:#F6931E; text-decoration:none; } 238 a:hover { color:silver; text-decoration:none; } 239 .bold { font-weight:bold; } 240 .field { text-align:center;padding:5px } 241 .field input { padding:5px; 242 243 } 244 245 .field input:focus { 246 247 } 248 249 .field input:hover { 250 251 } 252 #logo { 253 height:140px; 254 max-width:310px; 255 padding-right:5px; 256 margin-left:auto; 257 margin-right:auto; 258 margin-top:2%; 259 width:95%; 260 261 } 262 263 #login-admin { 264 margin-left:auto; 265 margin-right:auto; 266 margin-top:2%; 267 min-width:250px; 268 width:30%; 269 padding: 0px; 270 max-width:100%; 271 272 /* 273 274 */ 275 } 276 277 #login-admin div.panel { padding: 0 } 278 279 #login-admin label { display: none; text-align: right } 280 281 282 .admin-submit { text-align: center; padding-top:20px; } 283 284 .submit { } 285 286 287 288 .placeholder { color: #646667; font-style:italic } 289 290 ::-webkit-input-placeholder { font-style:italic; color: #bbb; } 291 292 :-moz-placeholder { font-style:italic; color: #bbb; } 293 294 h2 { text-align: center; color: #FAAD3D; } 295 296 #username {background: url(".e_IMAGE."admin_images/admins_16.png) no-repeat scroll 7px 9px; padding:7px; padding-left:30px; width:80%; max-width:218px; } 297 298 #userpass {background: url(".e_IMAGE."admin_images/lock_16.png) no-repeat scroll 7px 9px; padding:7px;padding-left:30px; width:80%; max-width:218px; } 299 300 #code-verify { width: 220px; padding: 7px; margin-left: auto; margin-right: auto; } 301 302 input[disabled] { color: silver; } 303 button[disabled] span { color: silver; } 304 .title_clean { display:none; } 305 306 "); 307 308 309 $obj = new auth; 310 $obj->authform(); 311 if (!defset('NO_HEADER')) 312 require_once (e_ADMIN."footer.php"); 313 exit; 314 } 315} 316 317//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------// 318class auth 319{ 320 321 /** 322 * Admin auth login 323 * @return null 324 */ 325 public function authform() // NOTE: this should NOT be a template of the admin-template, however themes may style it using css. 326 { 327 global $use_imagecode,$sec_img; 328 329 $pref = e107::getPref(); 330 $frm = e107::getForm(); 331 332 $incChap = (vartrue($pref['password_CHAP'], 0)) ? " onsubmit='hashLoginPassword(this)'" : ""; 333 334 // Start Clean 335 // NOTE: this should NOT be a template of the admin-template, however themes may style it using css. 336 337 $class = (e_QUERY == 'failed') ? "class='e-shake'" : ""; 338 339 340 341 $text = "<form id='admin-login' method='post' action='".e_SELF."' {$incChap} > 342 <div id='logo' ><img src='".e_IMAGE."logo_template_large.png' alt='".LAN_LOGIN."' /></div> 343 <div id='login-admin' class='center'> 344 <div>"; 345 346 if(e_QUERY == 'failed') 347 { 348 e107::lan('core', 'login'); 349 $text .= "<div class='alert alert-danger'>".LAN_LOGIN_21."</div>"; 350 $text .= "<script type='text/javascript'> 351 window.setTimeout(function() { 352 $('.alert').fadeTo(500, 0).slideUp(500, function(){ 353 $(this).remove(); 354 }); 355 }, 5000); 356 </script>"; 357 358 } 359 360 361 362 $text .= " 363 <div class='panel well panel-primary'> 364 <div class='panel-heading'><h3 class='panel-title'>".LAN_HEADER_04."</h3></div> 365 366 <div class='panel-body'> 367 <div class='field'> 368 <label for='username'>".ADLAN_89."</label> 369 <input class='tbox e-tip' type='text' autofocus required='required' name='authname' placeholder='".ADLAN_89."' id='username' size='30' value='' maxlength='".varset($pref['loginname_maxlength'], 30)."' /> 370 <div class='field-help' data-placement='right'>".LAN_ENTER_USRNAME_EMAIL."</div> 371 </div> 372 373 <div class='field'> 374 <label for='userpass'>".ADLAN_90."</label> 375 <input class='tbox e-tip' type='password' required='required' name='authpass' placeholder='".ADLAN_90."' id='userpass' size='30' value='' maxlength='30' /> 376 <div class='field-help' data-placement='right'>".LAN_PWD_REQUIRED."</div> 377 </div>"; 378 379 if ($use_imagecode) 380 { 381 $text .= " 382 <div class='field'> 383 <label for='code-verify'>".LAN_ENTER_CODE."</label>" 384 .$sec_img->renderImage(). 385 $sec_img->renderInput()." 386 </div>"; 387 } 388 389 $text .= "<div class='admin-submit'>" 390 .$frm->admin_button('authsubmit',ADLAN_91,'login'); 391 392 if (e107::getSession()->is('challenge') && varset($pref['password_CHAP'], 0)) 393 { 394 $text .= "<input type='hidden' name='hashchallenge' id='hashchallenge' value='".e107::getSession()->get('challenge')."' />\n\n"; 395 } 396 397 $text .= "</div></div> 398 </div> 399 </div> 400 </div> 401 </form>"; 402 403 e107::getRender()->tablerender("", $text, 'admin-login'); 404 echo "<div class='row-fluid'> 405 <div class='center' style='margin-top:25%; color:silver'><span style='padding:0 40px 0 0px;'><a target='_blank' href='http://e107.org'>".ADLAN_165."</a></span> <a href='".e_BASE."index.php'>".ADLAN_166."</a></div> 406 </div>"; 407 } 408 409 410 /** 411 * Admin auth check 412 * @param string $authname, entered name 413 * @param string $authpass, entered pass 414 * @param object $authresponse [optional] 415 * @return boolean if fail, else result array 416 */ 417 public function authcheck($authname, $authpass, $authresponse = '') 418 { 419 $pref = e107::getPref(); 420 $tp = e107::getParser(); 421 $sql_auth = e107::getDb('sql_auth'); 422 $user_info = e107::getUserSession(); 423 $reason = ''; 424 425 $authname = $tp->toDB(preg_replace("/\sOR\s|\=|\#/", "", trim($authname))); 426 $authpass = trim($authpass); 427 428 if ((($authpass == '') && ($authresponse == '')) || ($authname == '')) 429 $reason = 'np'; 430 if (strlen($authname) > varset($pref['loginname_maxlength'], 30)) 431 $reason = 'lu'; 432 433 if (!$reason) 434 { 435 if ($sql_auth->select("user", "*", "user_loginname='{$authname}' AND user_admin = 1 ")) 436 { 437 $row = $sql_auth->fetch(); 438 } 439 elseif ($sql_auth->select("user", "*", "(user_name='{$authname}' OR user_email='{$authname}' ) AND user_admin=1 ")) 440 { 441 $row = $sql_auth->fetch(); 442 $authname = $row['user_loginname']; 443 } 444 else 445 { 446 $reason = 'iu'; 447 } 448 } 449 450 if (!$reason && ($row['user_id'])) // Can validate password 451 { 452 $session = e107::getSession(); 453 if (($authresponse && $session->is('prevchallenge')) && ($authresponse != $session->get('prevchallenge'))) 454 { // Verify using CHAP (can't handle login by email address - only loginname - although with this code it does still work if the password is stored unsalted) 455 /* 456 $title = 'Login via admin'; 457 $extra_text = 'C: '.$session->get('challenge').' PC: '.$session->get('prevchallenge').' PPC: '.$session->get('prevprevchallenge').' R:'.$authresponse.' P:'.$row['user_password']; 458 $text = 'CHAP: '.$username.' ('.$extra_text.')'; 459 $title = e107::getParser()->toDB($title); 460 $text = e107::getParser()->toDB($text); 461 e107::getAdminLog()->e_log_event(4, __FILE__."|".__FUNCTION__."@".__LINE__, "LOGIN", $title, $text, FALSE, LOG_TO_ROLLING); 462 463 $logfp = fopen(e_LOG.'authlog.txt', 'a+'); fwrite($logfp, $title.': '.$text."\n"); fclose($logfp); 464 */ 465 466 if (($pass_result = $user_info->CheckCHAP($session->get('prevchallenge'), $authresponse, $authname, $row['user_password'])) !== PASSWORD_INVALID) 467 { 468 return $row; 469 } 470 } 471 else 472 { // Plaintext password 473 /* 474 $title = 'Login via admin'; 475 $extra_text = 'C: '.$session->get('challenge').' PC: '.$session->get('prevchallenge').' PPC: '.$session->get('prevprevchallenge').' R:'.$authresponse.' P:'.$row['user_password']; 476 $text = 'STD: '.$username.' ('.$extra_text.')'; 477 $title = e107::getParser()->toDB($title); 478 $text = e107::getParser()->toDB($text); 479 e107::getAdminLog()->e_log_event(4, __FILE__."|".__FUNCTION__."@".__LINE__, "LOGIN", $title, $text, FALSE, LOG_TO_ROLLING); 480 481// $logfp = fopen(e_LOG.'authlog.txt', 'a+'); fwrite($logfp, $title.': '.$text."\n"); fclose($logfp); 482 */ 483 484 if (($pass_result = $user_info->CheckPassword($authpass, $authname, $row['user_password'])) !== PASSWORD_INVALID) 485 { 486 return $row; 487 } 488 489 } 490 } 491 return array("authfail", "reason"=>$reason); 492 } 493} 494 495//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------// 496?> 497