<?php /* **** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE **** * * Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019 * * This file is licensed under the Embedded Projects General Public License *Version 3.1. * * You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis * to obtain the text of the corresponding license version. * **** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE **** */ ?> <?php use Xentral\Components\EnvironmentConfig\EnvironmentConfig; class Acl { protected $session_id; /** @var Application $app */ public function __construct($app) { $this->app = $app; } public function CheckTimeOut() { $this->session_id = session_id(); if(isset($_COOKIE['CH42SESSION']) && $_COOKIE['CH42SESSION']!='') { $this->session_id = $_COOKIE['CH42SESSION']; if(!(isset($_GET) && isset($_GET['module']) && isset($_GET['action']) && $_GET['module'] == 'welcome' && $_GET['action'] == 'poll'))$this->app->DB->Update("UPDATE useronline SET time=NOW(),login=1 WHERE sessionid='".$this->app->DB->real_escape_string($_COOKIE["CH42SESSION"])."' LIMIT 1"); } if (empty($this->session_id)) { return false; } // check if user is applied $sessid = $this->app->DB->Select("SELECT sessionid FROM useronline,user WHERE login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1' LIMIT 1"); if($this->session_id == $sessid) { // check if time is expired $time = $this->app->DB->Select("SELECT UNIX_TIMESTAMP(time) FROM useronline,user WHERE login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1' LIMIT 1"); if(($this->app->DB->Select('SELECT UNIX_TIMESTAMP(now())')-$time) > $this->app->Conf->WFconf['logintimeout']) { if(!isset($_COOKIE['CH42SESSION']) || $_COOKIE['CH42SESSION']=='') { $this->Logout("Ihre Zeit ist abgelaufen, bitte melden Sie sich erneut an.",true); return false; } } else { // update time if(!(isset($_GET) && isset($_GET['module']) && isset($_GET['action']) && $_GET['module'] == 'welcome' && $_GET['action'] == 'poll'))$this->app->DB->Update("UPDATE useronline,user SET useronline.time=NOW() WHERE login='1' AND sessionid='".$this->app->DB->real_escape_string($this->session_id)."' AND user.id=useronline.user_id AND user.activ='1'"); session_write_close(); // Blockade wegnehmen return true; } } } /** * @param string $usertype * @param string $module * @param string $action * @param string $userid * * @return bool */ public function Check($usertype,$module,$action, $userid='') { $ret = false; $permissions = !empty($this->app->Conf->WFconf['permissions']) && !empty($this->app->Conf->WFconf['permissions'][$usertype]) && isset($this->app->Conf->WFconf['permissions'][$usertype][$module]) ?$this->app->Conf->WFconf['permissions'][$usertype][$module] :null; if($usertype==='admin'){ return true; } if($this->app->User->GetID() > 0) { if($module==='ajax') { return true; } if($module === 'welcome') { if( in_array( $action, [ 'css', 'logo', 'start', 'meineapps', 'spooler', 'redirect', 'login', 'logout', 'passwortvergessen', ] ) ) { return true; } } if($module === 'gpsstechuhr') { if(in_array($action, ['create','save'])) { return true; } } if($module === 'learningdashboard') { if(in_array($action, ['list', 'ajax', ''])) { return true; } } if($module==='drucker' && $action==='spoolerdownload') { return true; } if($module==='wizard' && $action==='ajax') { return true; } if($module==='supersearch' && $action==='ajax') { return true; } if($module === 'appstore' && $action = 'list') { return true; } } // Change Userrights with new 'userrights'-Table if(!is_array($permissions)) { $permissions = []; } if(is_numeric($userid) && $userid>0) { $permission_db = $this->app->DB->Select("SELECT permission FROM userrights WHERE module='".$this->app->DB->real_escape_string($module)."' AND action='".$this->app->DB->real_escape_string($action)."' AND user='$userid' LIMIT 1"); $actionkey = array_search($action, $permissions); if($actionkey===false) { if($permission_db=='1') $permissions[] = $action; }else { if($permission_db=='0'){ unset($permissions[$actionkey]); $permissions = array_values($permissions); } } } // --- END --- foreach($permissions as $key => $val) { if($val==$action) { $ret = true; break; } } if($action=='' && $module==''){ $ret = true; } if($module === 'welcome' && in_array($action, array('login','main','logout'))) { $ret = true; } if($ret && $usertype!=='admin') { $id = (int)$this->app->Secure->GetGET('id'); if($id) { if( $action === 'edit' || $action === 'delete' || $action === 'copy' || $action === 'dateien' || ($action === 'rollen' && $module === 'adresse') || $action === 'inlinepdf' || $action === 'pdf' || $action === 'send' ) { switch($module) { case 'auftrag': case 'rechnung': case 'gutschrift': case 'angebot': case 'anfrage': case 'lieferschein': $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && ($this->app->DB->Select("SELECT a.id FROM adresse a INNER JOIN $module t ON a.id = t.adresse WHERE t.id = '$id' AND a.vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0 || $this->app->DB->Select("SELECT usereditid FROM $module t WHERE t.id = '$id' AND t.usereditid = '".$this->app->User->GetID()."' LIMIT 1"))); break; case 'dateien': $sql = "SELECT objekt FROM datei_stichwoerter WHERE datei = %s LIMIT 1"; $dateiModul = strtolower($this->app->DB->Select(sprintf($sql,$id))); //TODO datei_stichwoerter.objekt ist nicht zuverlässig für alle Datentypen. Deswegen nur zur Absicherung der bekannten Fälle #604706 if(array_search($dateiModul,['auftrag','rechnung','lieferschein','bestellung','angebot','verbindlichkiet','proformarechnung','anfrage','artikel','adresse','produktion'])!==false){ $sql = "SELECT parameter FROM datei_stichwoerter WHERE datei = %s"; $idModul = $this->app->DB->Select(sprintf($sql,$id)); $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $dateiModul WHERE id = '$idModul'")); } break; case 'konten': case 'artikel': case 'onlineshops': case 'benutzer': case 'bestellung': case 'produktion': $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")); break; case 'adresse': $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && $this->app->DB->Select("SELECT id FROM adresse WHERE id = '$id' AND vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0); break; } } else { $modact = array('artikel'=>array('einkauf', 'dateien','eigenschaften','verkauf','statistik','etikett','offenebestellungen','offeneauftraege','zertifikate','fremdnummern') ,'adresse' => array('rollen','ansprechpartner','lieferadresse','accounts','brief','belege','kundeartikel','abrechnungzeit','artikel','service','serienbrief') ,'lieferschein' => array('paketmarke') ); foreach($modact as $mod => $actarr) { if($module == $mod) { foreach($actarr as $v) { if($v == $action) { if($module === 'adresse') { $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")) || ($this->app->erp->ModulVorhanden('vertriebscockpit') && $this->app->DB->Select("SELECT id FROM adresse WHERE id = '$id' AND vertrieb = '".$this->app->User->GetAdresse()."' LIMIT 1") > 0); }else{ $ret = $this->app->erp->UserProjektRecht($this->app->DB->Select("SELECT projekt FROM $module WHERE id = '$id'")); } } } } } } } } // wenn es nicht erlaubt ist if($ret!=true) { if($this->app->User->GetID()<=0) { $this->app->erp->Systemlog("Keine gueltige Benutzer ID erhalten",1); echo str_replace('BACK',"index.php?module=welcome&action=login",$this->app->Tpl->FinalParse("permissiondenied.tpl")); } else { $this->app->erp->Systemlog("Fehlendes Recht",1); echo str_replace('BACK',isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'',$this->app->Tpl->FinalParse("permissiondenied.tpl")); } http_response_code(401); exit; } return $ret; } /** * @param int $userId * @param int $addressId * * @return array */ public function getEmailAddressFromUserAddress(int $userId, int $addressId): array { $mailAddress = trim((string)$this->app->DB->Select( "SELECT `email` FROM `adresse` WHERE `id` = '{$addressId}' AND `geloescht` <> 1 LIMIT 1" )); $mailAddresses = []; if($mailAddress !== '') { $mailAddresses[] = $mailAddress; } $isUserAdmin = $this->app->DB->Select( "SELECT `id` FROM `user` WHERE `id` = '{$userId}' AND `type` = 'admin' LIMIT 1" ) > 0; if(!$isUserAdmin) { return $mailAddresses; } $mailAddress = trim((string)$this->app->erp->Firmendaten('email')); if($mailAddress !== '' && $mailAddress !== 'mail@ihr_mail_server.de') { $mailAddresses[] = $mailAddress; } /** @var EnvironmentConfig $environmentConfig */ $environmentConfig = $this->app->Container->get('EnvironmentConfig'); $mailAddresses = array_merge($mailAddresses, $environmentConfig->getSystemFallbackEmailAddresses()); return array_unique($mailAddresses); } public function Passwortvergessen() { $code = $this->app->Secure->GetGET('code'); $vergessenusername = $this->app->Secure->GetPOST('vergessenusername'); $aendern = $this->app->Secure->GetPOST('aendern'); $this->app->DB->Update("UPDATE `user` SET vergessencode = '' WHERE vergessencode <> '' AND (isnull(`vergessenzeit`) OR `vergessenzeit` = '0000-00-00 00:00:00' OR now() > DATE_ADD(`vergessenzeit`, INTERVAL 1 DAY) )"); if($code) { $user = $this->app->DB->Select("SELECT id FROM `user` WHERE vergessencode <> '' AND vergessencode = '$code' LIMIT 1"); if($user) { if($aendern) { $passwortwiederholen = $this->app->Secure->GetPOST('passwortwiederholen'); $passwort = $this->app->Secure->GetPOST('passwort'); if((string)$passwort !== '') { if($passwort === $passwortwiederholen) { if(strlen($passwort) >= 6) { $salt = hash('sha512',microtime(true)); $passwordsha512 = $this->app->DB->real_escape_string(hash('sha512', $_POST['passwort'].$salt)); $salt = $this->app->DB->real_escape_string($salt); $this->app->DB->Update("UPDATE `user` SET `vergessencode` = '',`fehllogins` = 0, `password` = '', `passwordmd5` = '',`passwordhash`='', `salt` = '$salt',`passwordsha512` = '".$passwordsha512."' WHERE `id` = '$user' LIMIT 1"); $this->app->DB->Delete("DELETE FROM `useronline` WHERE `user_id`='".$user."'"); $this->app->DB->Insert("INSERT INTO `useronline` (`user_id`,`sessionid`, `ip`, `login`, `time`) VALUES ('".$user."','".$this->session_id."','".$_SERVER['REMOTE_ADDR']."','1',NOW())"); header('Location: index.php?module=welcome&action=start&msg='.$this->app->erp->base64_url_encode('<div class="info">Passwort wurde geändert</div>')); exit; } $this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', '<div style="fontsize=120%;font-weigt:bold;color:red; ">Das Passwort muss mindestens 6 Zeichen besitzen.</div>'); }else{ $this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', '<div style="fontsize=120%;font-weigt:bold;color:red; ">Passwörter stimmen nicht überein.</div>'); } }else{ $this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', '<div style="fontsize=120%;font-weigt:bold;color:red; ">Bitte ein Passwort eingeben.</div>'); } } $this->app->Tpl->Set('VORZURUECKSETZEN', '<!--'); $this->app->Tpl->Set('NACHZURUECKSETZEN', '-->'); $this->app->Tpl->Set('USERNAME', $this->app->DB->Select("SELECT `username` FROM `user` WHERE `id` = '$user' LIMIT 1")); }else{ $this->app->Tpl->Set('SPERRMELDUNGNACHRICHT', '<div style="fontsize=120%;font-weigt:bold;color:red; ">Der Link ist nicht mehr gültig.</div>'); $this->app->Tpl->Set('VORPASSWORT', '<!--'); $this->app->Tpl->Set('NACHPASSWORT', '-->'); } } else{ if((string)$vergessenusername !== '') { $user = $this->app->DB->SelectRow( "SELECT `id`, `adresse` FROM `user` WHERE `activ` = 1 AND `username` = '{$vergessenusername}' LIMIT 1" ); $userId = $user['id'] ?? null; $addressId = $user['adresse'] ?? null; $emailAddresses = []; $mailSuccessfullySent = false; if($userId > 0) { $emailAddresses = $this->getEmailAddressFromUserAddress((int)$userId, (int)$addressId); } if(!empty($emailAddresses)) { $name = $vergessenusername; $anrede = ''; if($addressId > 0) { $addressFields = $this->app->DB->SelectRow( "SELECT `name`, `anschreiben` FROM `adresse` WHERE `id` = '{$addressId}' LIMIT 1" ); $name = $addressFields['name'] ?? null; $anrede = $addressFields['anschreiben'] ?? null; } $code = sha1(microtime(true)); if( !$this->app->DB->Select( "SELECT `id` FROM `user` WHERE `id` = '{$userId}' AND `vergessencode` <> '' AND ifnull(`vergessenzeit`, '0000-00-00 00:00:00') <> '0000-00-00 00:00:00' AND `vergessenzeit` > DATE_SUB(now(), INTERVAL 5 MINUTE) LIMIT 1" ) ) { $this->app->DB->Update( "UPDATE `user` SET `vergessencode` = '{$code}', `vergessenzeit` = now() WHERE `id` = '{$userId}' LIMIT 1" ); $language = $this->app->DB->Select("SELECT `sprachebevorzugen` FROM `user` WHERE `id`='{$userId}' LIMIT 1"); if($language==''){ $language = $this->app->DB->Select("SELECT `sprache` FROM `adresse` WHERE `id`='{$addressId}' LIMIT 1"); } if($language == ''){ $language = 'deutsch'; } $mailContent = $this->app->erp->GetGeschaeftsBriefText('passwortvergessen', $language, 0); $mailSubject = $this->app->erp->GetGeschaeftsBriefBetreff('passwortvergessen', $language, 0); if((string)$mailContent === '' && $language !== 'deutsch') { $language = 'deutsch'; $mailContent = $this->app->erp->GetGeschaeftsBriefText('passwortvergessen', $language, 0); $mailSubject = $this->app->erp->GetGeschaeftsBriefBetreff('passwortvergessen', $language ,0); } if((string)$mailSubject === '') { $mailSubject = 'Xentral Passwort zurücksetzen'; } if((string)$mailContent === '') { $mailContent = "{ANREDE} {NAME} Bitte klicken Sie auf dem Link <a href=\"{URL}\">{URL}</a> um Ihr Xentral-Passwort zu ändern"; } $server = ''; $isSecure = false; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { $isSecure = true; } elseif ((!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on')) { $isSecure = true; } $REQUEST_PROTOCOL = $isSecure ? 'https' : 'http'; if($_SERVER['SERVER_NAME']!='' && $_SERVER['SERVER_NAME'] !== '_') //MAMP auf macos { $server = $REQUEST_PROTOCOL.'://'.$_SERVER['SERVER_NAME'].(($_SERVER['SERVER_PORT']!=80 && $_SERVER['SERVER_PORT'] != 433)?":".$_SERVER['SERVER_PORT']:'').$_SERVER['REQUESR_URI'].$_SERVER['SCRIPT_NAME']; } elseif($_SERVER['SCRIPT_URI'] != '') { $server = $_SERVER['SCRIPT_URI']; } elseif($_SERVER['REQUEST_URI'] != '' && $_SERVER['SERVER_ADDR']!='' && $_SERVER['SERVER_ADDR']!=='::1' && strpos($_SERVER['SERVER_SOFTWARE'],"nginx")===false) { $server = (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR']?$REQUEST_PROTOCOL.'://'.$_SERVER['SERVER_ADDR'].(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443?':'.$_SERVER['SERVER_PORT']:''):'').$_SERVER['SCRIPT_NAME']; } $pos = strripos($server, 'index.php'); if($pos) { $server = rtrim(substr($server, 0, $pos), '/') . '?module=welcome&action=passwortvergessen&code=' . $code; } else { $server .= '/index.php?module=welcome&action=passwortvergessen&code=' . $code; } $serverLocation = $this->app->Location->getServer(); if(!empty($serverLocation)) { $server = rtrim($serverLocation,'/') . '?module=welcome&action=passwortvergessen&code=' . $code; } foreach(['default', 'fallback'] as $sentSetting) { if($sentSetting === 'fallback') { $db = $this->app->Conf->WFdbname; if( empty(erpAPI::Ioncube_Property('cloudemail')) || $this->app->erp->firmendaten[$db]['email'] === erpAPI::Ioncube_Property('cloudemail') ) { break; } $this->app->erp->firmendaten[$db]['mailanstellesmtp'] = 1; $this->app->erp->firmendaten[$db]['email'] = erpAPI::Ioncube_Property('cloudemail'); } foreach ($emailAddresses as $email) { $recipientMailAddress = $email; $recipientName = $name; if(empty($recipientMailAddress) || empty($recipientName)) { continue; } $mailContent = str_replace(['{NAME}', '{ANREDE}', '{URL}'], [$recipientName, $anrede, $server], $mailContent); if(!$this->app->erp->isHTML($mailContent)){ $mailContent = str_replace("\r\n", '<br>', $mailContent); } $mailSuccessfullySent = $this->app->erp->MailSend( $this->app->erp->GetFirmaMail(), $this->app->erp->GetFirmaAbsender(), $recipientMailAddress, $recipientName, $mailSubject, $mailContent, '', 0, true, '', '', true ); if($mailSuccessfullySent){ break 2; } } } } } if($mailSuccessfullySent || $userId <= 0) { $this->app->Tpl->Set( 'SPERRMELDUNGNACHRICHT', '<div>Bitte prüfen Sie Ihr E-Mail-Postfach. Falls keine E-Mail angekommen ist wenden Sie sich bitte an den Administrator.</div>' ); } elseif(empty($emailAddresses)) { $this->app->Tpl->Set( 'SPERRMELDUNGNACHRICHT', '<div>Es ist keine Email hinterlegt. Bitte wenden Sie sich an den Administrator.</div>' ); } else{ $this->app->Tpl->Set( 'SPERRMELDUNGNACHRICHT', '<div>Es ist ein Fehler beim Senden der Email aufgetreten. Bitte wenden Sie sich an den Administrator.</div>' ); } } $this->app->Tpl->Set('VORPASSWORT', '<!--'); $this->app->Tpl->Set('NACHPASSWORT', '-->'); } $this->app->Tpl->Parse('PAGE','passwortvergessen.tpl'); } /** * @param int|null $id * * @return bool|int */ public function IsAdminadmin($id = null) { if($id === null && !empty($this->app->User) && method_exists($this->app->User, 'GetID')) { $id = $this->app->User->GetID(); } if(!$id) { return false; } $userarr = $this->app->DB->SelectRow("SELECT * FROM `user` WHERE id = '$id' AND activ = 1 AND ifnull(hwtoken, 0) = 0 LIMIT 1"); if(empty($userarr)) { return false; } $hash = 'isadminadmin_'.md5(json_encode($userarr)); $cache = (string)$this->app->User->GetParameter($hash); if($cache !== '') { $cache = (int)$cache; if($cache === 0) { return false; } if($cache === 1) { return true; } if($cache === 2) { return 2; } } $lastCache = $this->app->User->GetParameter('isadminadmin_lastcache'); $isSameHash = $lastCache === $hash; if((string)$lastCache !== '' && !$isSameHash){ $this->app->User->deleteParameter($lastCache); } if(!$isSameHash) { $this->app->User->SetParameter('isadminadmin_lastcache', $hash); } if($userarr['passwordhash'] != '' && password_verify ( 'admin' , $userarr['passwordhash'] )) { $this->app->User->SetParameter($hash, 1); return true; } if($userarr['passwordhash'] != '') { $ret = password_verify ( $userarr['username'] , $userarr['passwordhash'] )?2:false; $this->app->User->SetParameter($hash, (int)$ret); return $ret; } if($userarr['passwordsha512'] != '' && hash('sha512','admin'.$userarr['salt']) === $userarr['passwordsha512']) { $this->app->User->SetParameter($hash, 1); return true; } if($userarr['passwordsha512'] != '') { $ret = hash('sha512',$userarr['username'].$userarr['salt']) === $userarr['passwordsha512']?2:false; $this->app->User->SetParameter($hash, (int)$ret); return $ret; } if(md5('admin') == $userarr['passwordmd5']) { $this->app->User->SetParameter($hash, 1); return true; } $ret = md5($userarr['username']) == $userarr['passwordmd5']?2:false; $this->app->User->SetParameter($hash, (int)$ret); return $ret; } public function Login() { $this->refresh_githash(); include dirname(__DIR__).'/../version.php'; $this->app->Tpl->Set('XENTRALVERSION',"V.".$version_revision); $this->app->Tpl->Set('LOGINWARNING_VISIBLE', 'hidden'); $result = $this->CheckHtaccess(); if ($result !== true) { $this->app->Tpl->Set('LOGINWARNING_VISIBLE', ''); $this->app->Tpl->Set('LOGINWARNING_TEXT', "Achtung: Zugriffskonfiguration (htaccess) fehlerhaft. Bitte wenden Sie sich an Ihren an Ihren Administrator. <br>($result)"); } if($this->IsInLoginLockMode() === true) { $this->app->Tpl->Set('LOGINWARNING_VISIBLE', ''); $this->app->Tpl->Set('LOGINWARNING_TEXT', 'Achtung: Es werden gerade Wartungsarbeiten in Ihrem System (z.B. Update oder Backup) durch Ihre IT-Abteilung durchgeführt. Das System sollte in wenigen Minuten wieder erreichbar sein. Für Rückfragen wenden Sie sich bitte an Ihren Administrator.'); } $multidbs = $this->app->getDbs(); if(count($multidbs) > 1) { $options = ''; foreach($multidbs as $k => $v) { $options .= '<option value="'.$k.'">'.$v.'</options>'; } $this->app->Tpl->Add( 'MULTIDB', '<div class="field"> <select id="db" name="db"> <option value="'.$this->app->Conf->WFdbname.'">- System wählen -</option> '.$options.' </select><input type="hidden" name="dbselect" value="true"> </div>' ); } $username = $this->app->DB->real_escape_string($this->app->Secure->GetPOST("username")); $password = $this->app->Secure->GetPOST("password"); $passwordunescaped = $this->app->Secure->GetPOST('password',"","","noescape"); $stechuhrdevice = $this->app->Secure->GetPOST('stechuhrdevice'); $rfidcode = $this->app->Secure->GetPOST('rfidcode'); $rfid = $this->app->Secure->GetPOST('rfid'); $code = $this->app->Secure->GetPOST('code'); $adminadmin = false; if(strtolower($username) === 'admin' && $password === 'admin') { $adminadmin = true; } elseif($username === $password) { $adminadmin = 2; } $token = $this->app->Secure->GetPOST("token"); if($username==''&& ($password=='' || $token=='') && $stechuhrdevice == '' && $rfid == ''){ setcookie('nonavigation',false); if($this->app->DB->connection) $this->app->Tpl->Set('LOGINMSG','Bitte geben Sie Benutzername und Passwort ein.'); else $this->app->Tpl->Set('LOGINMSG', '<div style="fontsize=120%;font-weigt:bold;color:red; ">Fehler: Keine Verbindung zur Datenbank möglich!</div>'); if($this->app->erp->UserDevice()==='smartphone') { $this->app->Tpl->Parse('PAGE','login_smartphone.tpl'); } else { $this->selectLanguageOptionByServerVariable(); $this->app->Tpl->Parse('PAGE','login.tpl'); } } else { // Benutzer hat Daten angegeben $userdata = $this->app->DB->SelectArr("SELECT * FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); if($userdata) { $userdata = reset($userdata); } $encrypted = isset($userdata['encrypted'])?$userdata['encrypted']:''; $encrypted_md5 = isset($userdata['passwordmd5'])?$userdata['passwordmd5']:''; $fehllogins = isset($userdata['fehllogins'])?$userdata['fehllogins']:''; $type = isset($userdata['type'])?$userdata['type']:''; $externlogin = isset($userdata['externlogin'])?$userdata['externlogin']:''; $hwtoken = isset($userdata['hwtoken'])?$userdata['hwtoken']:''; $salt = isset($userdata['salt'])?$userdata['salt']:''; $usepasswordhash = true; $passwordhash = $this->app->DB->Select("SELECT passwordhash FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); if($this->app->DB->error())$usepasswordhash = false; $usesha512 = true; $passwordsha512 = $this->app->DB->Select("SELECT passwordsha512 FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); if($this->app->DB->error())$usesha512 = false; $stechuhrdevicelogin = false; // Xentral 20 database compatibility $check = $this->app->DB->Select("SHOW TABLES LIKE 'stechuhrdevice'"); $devices = null; if (!empty($check)) { $devices = $this->app->DB->SelectArr("SELECT * from stechuhrdevice where aktiv = 1 and code = '$code' AND code <> ''"); } if($devices) { foreach($devices as $device) { $IP = ip2long($_SERVER['REMOTE_ADDR']); $devIP = ip2long($device['IP']); $submask = ip2long($device['submask']); $maskIP = $IP & $submask; $dbIP = $devIP & $submask; if($maskIP == $dbIP) { $stechuhrdevicelogin = true; } } } if($code && !$stechuhrdevicelogin) { setcookie('nonavigation',false); $this->app->Tpl->Set('RESETSTORAGE',' if(typeof(Storage) !== "undefined") { var devicecode = localStorage.getItem("devicecode"); if(devicecode) { localStorage.setItem("devicecode", ""); } } if(typeof indexedDB != "undefined") { var request = indexedDB.open(\'wawisionstechuhrdevice\', 1); request.onupgradeneeded = function(){ var db = this.result; if(!db.objectStoreNames.contains(\'stechuhr\')){ store = db.createObjectStore(\'stechuhr\', { keyPath: \'key\', autoIncrement: true }); } }; request.onsuccess = function(){ var db = this.result; var trans = db.transaction([\'stechuhr\'], \'readonly\'); var store = trans.objectStore(\'stechuhr\'); var range = IDBKeyRange.lowerBound(0); var cursorRequest = store.openCursor(range); cursorRequest.onsuccess = function(evt){ var result = evt.target.result; if(result){ if(typeof result.value != \'undefined\' && typeof result.value.code != \'undefined\') { var trans2 = db.transaction([\'stechuhr\'], \'readwrite\'); var store2 = trans2.objectStore(\'stechuhr\'); var request2 = store2.delete(result.key); } } } } } '); } // try login and set user_login if login was successfull // wenn intern geht immer passwort??? // MOTP $user_id=""; $userip = $_SERVER['REMOTE_ADDR']; $ip_arr = explode('.',$userip); if($ip_arr[0]=="192" || $ip_arr[0]=="10" || $ip_arr[0]=="127" || $ip_arr[0]=="172") $localconnection = 1; else $localconnection = 0; if($stechuhrdevicelogin && $rfidcode) { $userarr = $this->app->DB->SelectArr("SELECT * FROM `user` WHERE rfidtag = '$rfidcode' AND rfidtag <> '' AND activ = 1 LIMIT 1"); if($userarr) { $userarr = reset($userarr); $user_id = $userarr['id']; }else{ $user_id = ''; } if($user_id) { $encrypted = $userarr['password']; $encrypted_md5 = $userarr['passwordmd5']; $fehllogins = $userarr['fehllogins']; $type = $userarr['type']; $externlogin = $userarr['externlogin']; $hwtoken = $userarr['hwtoken']; $stechuhruser = $userarr['stechuhrdevice']; $usesha512 = true; $salt = isset($userarr['salt'])?$userarr['salt']:''; $passwordsha512 = isset($userarr['passwordsha512'])?$userarr['passwordsha512']:''; if(!isset($userarr['passwordsha512'])) { $usesha512 = false; } if($rfid == ''){ if($stechuhrdevice == $stechuhruser) { setcookie('nonavigation',true); } elseif($stechuhruser == "") { $this->app->DB->Update("UPDATE `user` set stechuhrdevice = '$stechuhrdevice' where id = '$user_id' LIMIT 1"); setcookie('nonavigation',true); } else { $user_id = ""; setcookie('nonavigation',false); } } } } elseif($stechuhrdevicelogin && $stechuhrdevice) { $nr = substr($stechuhrdevice,0,6); if(is_numeric($nr) && strlen($stechuhrdevice) >= 6) { $userarr = $this->app->DB->SelectArr("SELECT * FROM `user` WHERE (username = '$nr' OR username = '$stechuhrdevice') and hwtoken = 4 AND activ = 1 LIMIT 1"); if($userarr) { $userarr = reset($userarr); $user_id = $userarr['id']; }else $user_id = ''; if($user_id) { $encrypted = $userarr['password']; $encrypted_md5 = $userarr['passwordmd5']; $fehllogins = $userarr['fehllogins']; $type = $userarr['type']; $externlogin = $userarr['externlogin']; $hwtoken = $userarr['hwtoken']; $stechuhruser = $userarr['stechuhrdevice']; $usesha512 = true; $salt = isset($userarr['salt'])?$userarr['salt']:''; $passwordsha512 = isset($userarr['passwordsha512'])?$userarr['passwordsha512']:''; if(!isset($userarr['passwordsha512'])) { $usesha512 = false; } $stechuhruser = $this->app->DB->Select("SELECT stechuhrdevice FROM `user` WHERE id = '$user_id'"); { if($stechuhrdevice == $stechuhruser) { setcookie('nonavigation',true); } elseif($stechuhruser == '') { $this->app->DB->Update("UPDATE `user` set stechuhrdevice = '$stechuhrdevice' where id = '$user_id' LIMIT 1"); setcookie('nonavigation',true); } else { $user_id = ''; setcookie('nonavigation',false); } } } } } elseif($hwtoken==5) //ldap { // verbinden zum ldap server $ds = ldap_connect($this->app->erp->Firmendaten("ldap_host")); ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); $suche = $this->app->erp->Firmendaten("ldap_searchbase"); $filter = str_replace('{USER}',$username,$this->app->erp->Firmendaten("ldap_filter")); $bind_name = str_replace('{USER}',$username,$this->app->erp->Firmendaten("ldap_bindname")); if ($ds) { // binden zum ldap server $ldapbind = ldap_bind($ds, $bind_name, $password); if($filter!="") { // pruefe ob ein treffer in der Liste ist $sr=ldap_search($ds,$suche, $filter); if(ldap_count_entries($ds,$sr) > 0) $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); else $user_id =''; } else { if($ldapbind) $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); else $user_id =''; } } else { $user_id =''; } } //wawision otp else if ($hwtoken==3) { setcookie('nonavigation',false); $wawi = new WaWisionOTP(); $hwkey = $this->app->DB->Select("SELECT hwkey FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); $hwcounter = $this->app->DB->Select("SELECT hwcounter FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); $hwdatablock = $this->app->DB->Select("SELECT hwdatablock FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); //$wawi->SetKey($hwkey); //$wawi->SetCounter($hwcounter); $serial =$hwdatablock; //$key = pack('V*', 0x01,0x02,0x03,0x04); $hwkey = trim(str_replace(' ','',$hwkey)); $hwkey_array = explode(",",$hwkey); $key = pack('V*', $hwkey_array[0], $hwkey_array[1], $hwkey_array[2], $hwkey_array[3]); $check = (int)$wawi->wawision_pad_verify($token,$key,$serial); // Fix fuer HW if($check >= 2147483647) $check = 0; if($encrypted_md5!="") { if ( $check > 0 && (md5($password) == $encrypted_md5 || md5($passwordunescaped) == $encrypted_md5) && $fehllogins<8 && $check > $hwcounter) { $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); // Update counter $this->app->DB->Update("UPDATE `user` SET hwcounter='$check' WHERE id='$user_id' LIMIT 1"); $this->app->erp->SystemLog("Xentral Login OTP Success User: $username Token: $token"); } else { if($check===false) { $this->app->erp->SystemLog("Xentral Login OTP Falscher Key (Unkown Key) User: $username Token: $token"); } else if ($check < $hwcounter && $check > 0) { $this->app->erp->SystemLog("Xentral Login OTP Counter Fehler (Replay Attacke) User: $username Token: $token"); } $user_id = ''; } } else { $user_id = ''; } } else { setcookie('nonavigation',false); if(isset($passwordhash) && $passwordhash != '' && $usepasswordhash) { $checkunescaped = password_verify ( $passwordunescaped , $passwordhash ); if(!$checkunescaped) { $checkescaped = password_verify ( $password , $passwordhash ); }else { $checkescaped = false; } $passwordValid = $checkunescaped || $checkescaped; if($passwordValid){ $this->app->erp->RunHook('login_password_check_otp', 3, $userdata['id'], $token, $passwordValid); } if($passwordValid) { $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); if($checkescaped && $user_id) { $options = array( 'cost' => 12, ); $passwordhash = @password_hash($passwordunescaped, PASSWORD_BCRYPT, $options); $this->app->DB->Update("UPDATE `user` SET passwordhash = '".$this->app->DB->real_escape_string($passwordhash)."', password='',passwordmd5='', salt = '', passwordsha512 = '' WHERE id = '".$user_id."' LIMIT 1"); } }else{ $user_id = ''; } } elseif(!empty($passwordsha512) && $usesha512) { if(hash('sha512',$passwordunescaped.$salt) === $passwordsha512 && $fehllogins<8) { $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); $passwordValid = true; $token = $this->app->Secure->GetPOST('token'); $this->app->erp->RunHook('login_password_check_otp', 3, $user_id, $token, $passwordValid); if(!$passwordValid){ $user_id = false; } } else { $user_id = ''; } } elseif($encrypted_md5!='') { if ((md5($password ) == $encrypted_md5 || md5($passwordunescaped) == $encrypted_md5) && $fehllogins<8) { if(isset($this->app->Conf->WFdbType) && $this->app->Conf->WFdbType=="postgre"){ $user_id = $this->app->DB->Select("SELECT id FROM \"user\" WHERE username='".$username."' AND activ='1' LIMIT 1"); } else { $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); } if($user_id && $usesha512) { $salt = $this->app->DB->Select("SELECT salt FROM `user` WHERE id = '$user_id' LIMIT 1"); $sha512 = $this->app->DB->Select("SELECT passwordsha512 FROM `user` WHERE id = '$user_id' LIMIT 1"); if(empty($salt) && empty($sha512)) { $salt = hash('sha512',microtime(true)); $sha512 = hash('sha512',$passwordunescaped.$salt); $this->app->DB->Update("UPDATE `user` SET salt = '$salt', passwordsha512 = '$sha512' WHERE id = '$user_id' LIMIT 1"); } } } else { $user_id = ''; } } else { if (((crypt( $password, $encrypted ) == $encrypted) || (crypt( $passwordunescaped, $encrypted ) == $encrypted)) && $fehllogins<8) { if(isset($this->app->Conf->WFdbType) && $this->app->Conf->WFdbType=="postgre"){ $user_id = $this->app->DB->Select("SELECT id FROM \"user\" WHERE username='".$username."' AND activ='1' LIMIT 1"); } else { $user_id = $this->app->DB->Select("SELECT id FROM `user` WHERE username='".$username."' AND activ='1' LIMIT 1"); } if($user_id && $usesha512) { $salt = $this->app->DB->Select("SELECT salt FROM `user` WHERE id = '$user_id' LIMIT 1"); $sha512 = $this->app->DB->Select("SELECT passwordsha512 FROM `user` WHERE id = '$user_id' LIMIT 1"); if(empty($salt) && empty($sha512)) { $salt = hash('sha512',microtime(true)); $sha512 = hash('sha512',$passwordunescaped.$salt); $this->app->DB->Update("UPDATE `user` SET salt = '$salt', passwordsha512 = '$sha512' WHERE id = '$user_id' LIMIT 1"); } } } else { $user_id = ''; } } } //$password = substr($password, 0, 8); //TODO !!! besseres verfahren!! //pruefen ob extern login erlaubt ist!! // wenn keine externerlogin erlaubt ist und verbindung extern if($externlogin==0 && $localconnection==0) { $this->app->Tpl->Set('LOGINERRORMSG',"Es ist kein externer Login mit diesem Account erlaubt."); $this->selectLanguageOptionByServerVariable(); $this->app->Tpl->Parse('PAGE','login.tpl'); } else if(is_numeric($user_id)) { $this->app->DB->Delete("DELETE FROM useronline WHERE user_id='".$user_id."'"); if (empty($this->session_id)) { throw new RuntimeException('Session ID can not be empty.'); } $this->app->DB->Insert("INSERT INTO useronline (user_id, sessionid, ip, login, time) VALUES ('".$user_id."','".$this->session_id."','".$_SERVER['REMOTE_ADDR']."','1',NOW())"); $this->app->DB->Select("UPDATE `user` SET fehllogins=0 WHERE username='".$username."' LIMIT 1"); $language = $this->app->Secure->GetPOST('language'); $this->app->User->SetParameter('wawisionuebersetzung_sprache', $language); $this->app->erp->calledOnceAfterLogin($type); $this->app->User->createCache(); if($adminadmin && !$this->app->DB->Select("SELECT id FROM `user` WHERE id = '$user_id' AND type = 'admin' LIMIT 1")) { $adminadmin = false; } //$module=$this->app->Secure->GetGET("module"); //$action=$this->app->Secure->GetGET("action"); //$id=$this->app->Secure->GetGET("id"); if($adminadmin) { //$startseite = "index.php?module=welcome&action=settings&msg=".$this->app->erp->base64_url_encode('<div class="error">Bitte ändern Sie Ihr Passwort. Das Passwort entspricht noch dem Passwort der Installation!</div>'); $startseite = 'index.php?module=welcome&action=start'; $this->app->erp->Startseite($startseite); exit; } if($code && !$this->app->Secure->GetPOST('username')) { $result = $this->app->DB->SelectArr("SELECT url, reduziert FROM stechuhrdevice WHERE code = '$code' AND aktiv = 1 LIMIT 1"); $startseite = $result[0]['url'] ; $isReduziert = $result[0]['reduziert']; if($isReduziert){ $this->app->User->SetParameter('stechuhrdevicereduziert',true); } if($isReduziert && empty($startseite)){ $startseite = 'index.php?module=stechuhr&action=list&prodcmd=arbeitsschritt'; } if($startseite) { $this->app->erp->Startseite($startseite); exit; } } $ref = $_SERVER['HTTP_REFERER']; $refData = parse_url($ref); if($refData['query']!='' && !(strpos($ref, 'module=welcome') !== false && strpos($ref, 'action=login') !== false)) { header('Location: index.php?'.$refData['query']); exit; } $this->app->erp->Startseite(); exit; } else if ($fehllogins>=8) { $this->app->Tpl->Set('LOGINERRORMSG','Max. Anzahl an Fehllogins erreicht. Bitte wenden Sie sich an Ihren Administrator.'); $this->selectLanguageOptionByServerVariable(); $this->app->Tpl->Parse('PAGE','login.tpl'); } else { if(isset($this->app->Conf->WFdbType) && $this->app->Conf->WFdbType=="postgre") $this->app->DB->Select("UPDATE `user` SET fehllogins=fehllogins+1 WHERE username='".$username."'"); else $this->app->DB->Select("UPDATE `user` SET fehllogins=fehllogins+1 WHERE username='".$username."' LIMIT 1"); $this->app->Tpl->Set('LOGINERRORMSG','Benutzername oder Passwort falsch.'); $this->selectLanguageOptionByServerVariable(); $this->app->Tpl->Parse('PAGE','login.tpl'); } //setcookie('DBSELECTED', '',-1); } } public function selectLanguageOptionByServerVariable(): void { $language = !isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])?'':strtoupper(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2)); switch($language) { case 'DE': $this->app->Tpl->Set('OPTIONLANGUAGEGERMAN', ' selected="selected" '); break; case 'EN': $this->app->Tpl->Set('OPTIONLANGUAGEENGLISH', ' selected="selected" '); break; } } public function Logout($msg='',$logout=false) { setcookie('DBSELECTED',''); if($logout) $this->app->Tpl->Parse('PAGE','sessiontimeout.tpl'); $userid = (int)$this->app->User->GetID(); if($userid) { $this->app->User->SetParameter('stechuhrdevicelogin', 0); $this->app->User->SetParameter('stechuhrdevicereduziert', false); } $this->app->DB->Delete("DELETE FROM `useronline` WHERE user_id='".$userid."'"); $this->app->erp->RunHook('logout'); @session_destroy(); if($userid > 0) { @session_start(); @session_regenerate_id(true); $_SESSION['database']=''; } if(!$logout) { $server = $this->app->Location->getServer(); if(!empty($server)) { header('Location: '.$server); }else{ header('Location: ' . $this->app->http . '://' . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['REQUEST_URI']), '/')); } exit; } } public function CreateAclDB() { } protected function mOTP($pin,$otp,$initsecret) { $maxperiod = 3*60; // in seconds = +/- 3 minutes $time=$this->app->DB->Select('SELECT UNIX_TIMESTAMP()');//gmdate('U'); for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++) { $md5 = substr(md5(substr($i,0,-1).$initsecret.$pin),0,6); if($otp == $md5) { return true; } } return false; } /** * @return bool */ private function IsInLoginLockMode() { if($this->app->erp->GetKonfiguration('login_lock_mode') === '1'){ $timeMaintenance = (int)$this->app->erp->GetKonfiguration('login_lock_mode_time'); if(empty($timeMaintenance)){ $this->app->erp->SetKonfigurationValue('login_lock_mode_time', time()); return true; } $timeOutMaintenance = (int)$this->app->erp->GetKonfiguration('login_lock_mode_timeout'); // default 10min $timeOut = empty($timeOutMaintenance) ? 600 : $timeOutMaintenance; if(time() - $timeMaintenance < $timeOut){ return true; } $this->app->erp->SetKonfigurationValue('login_lock_mode', 0); $this->app->erp->SetKonfigurationValue('login_lock_mode_time', 0); $this->app->erp->SetKonfigurationValue('login_lock_mode_timeout', 0); } return false; } // HTACCESS SECURITY // Check for correct .htaccess settings // true if ok, else error text protected function CheckHtaccess() { $nominal = array(' # Generated file from class.acl.php # For detection of htaccess functionality SetEnv HTTP_OPENXE_HTACCESS on # Disable directory browsing Options -Indexes # Set default page to index.php DirectoryIndex "index.php" # Deny general access Order deny,allow <FilesMatch "."> Order Allow,Deny Deny from all </FilesMatch> # Allow index.php <Files "index.php"> Order Allow,Deny Allow from all </Files> # end ', ' # Generated file from class.acl.php # Disable directory browsing Options -Indexes # Deny access to all *.php Order deny,allow Allow from all <FilesMatch "\.(css|jpg|jpeg|gif|png|svg|js|ico|css.map|js.map)$"> Order Allow,Deny Allow from all </FilesMatch> # Allow access to index.php <Files index.php> Order Allow,Deny Allow from all </Files> # Allow access to setup.php <Files setup.php> Order Allow,Deny Allow from all </Files> # Allow access to inline PDF viewer <Files viewer.html> Order Allow,Deny Allow from all </Files> <Files robots.txt> Order Allow,Deny Allow from all </Files> # end '); $script_file_name = $_SERVER['SCRIPT_FILENAME']; $htaccess_path = array( dirname(dirname($script_file_name))."/.htaccess", // root dirname($script_file_name)."/.htaccess"); // www for ($count = 0;$count < 2;$count++) { $htaccess = file_get_contents($htaccess_path[$count]); if ($htaccess === false) { $missing = true; } else { $htaccess = trim($htaccess); } $htaccess_nominal = trim($nominal[$count]); $result = strcmp($htaccess,$htaccess_nominal); if ($htaccess === false) { return($htaccess_path[$count]." nicht vorhanden."); } if ($result !== 0) { return($htaccess_path[$count]." fehlerhaft."); } } if (!isset($_SERVER['HTTP_OPENXE_HTACCESS'])) { return("htaccess nicht aktiv."); } return(true); // HTACCESS SECURITY END } function refresh_githash() { $gitinfo = array(); $path = '../.git/'; if (!is_dir($path)) { return; } $head = trim(file_get_contents($path . 'HEAD')); $refs = trim(substr($head,0,4)); if ($refs == 'ref:') { $ref = substr($head,5); $gitinfo['hash'] = trim(file_get_contents($path . $ref)); $gitinfo['branch'] = basename($path . $ref); } else { $gitinfo['hash'] = $head; } if (!empty($gitinfo)) { file_put_contents("../gitinfo.json", json_encode($gitinfo)); } } }