From: <ser...@us...> - 2014-08-19 11:44:28
|
Revision: 6832 http://sourceforge.net/p/web-erp/reponame/6832 Author: serakfalcon Date: 2014-08-19 11:44:16 +0000 (Tue, 19 Aug 2014) Log Message: ----------- Security update, changes algorithm for password hashing to be more secure for PHP versions 5.3.7+. For new installs,the $CryptFunction global is removed and is no longer needed. For existing installs, $CryptFunction will be needed until all users have logged in at least once or have had their password reset. Modified Paths: -------------- trunk/UserSettings.php trunk/api/api_session.inc trunk/config.distrib.php trunk/includes/UserLogin.php trunk/includes/session.inc trunk/sql/mysql/country_sql/default.sql trunk/sql/mysql/country_sql/demo.sql trunk/sql/mysql/country_sql/weberpchina.sql Modified: trunk/UserSettings.php =================================================================== --- trunk/UserSettings.php 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/UserSettings.php 2014-08-19 11:44:16 UTC (rev 6832) @@ -2,11 +2,11 @@ /* $Id$*/ -include('includes/session.inc'); +include('includes/session_views.inc'); $Title = _('User Settings'); -include('includes/header.inc'); +include('includes/header_views.inc'); -echo '<p class="page_title_text"><img src="'.$RootPath.'/css/'.$Theme.'/images/user.png" title="' . +echo '<p class="page_title_text"><img src="'.$MainView->getStyleLink() .'/images/user.png" title="' . _('User Settings') . '" alt="" />' . ' ' . _('User Settings') . '</p>'; $PDFLanguages = array(_('Latin Western Languages - Times'), @@ -90,76 +90,58 @@ // update the session variables to reflect user changes on-the-fly $_SESSION['DisplayRecordsMax'] = $_POST['DisplayRecordsMax']; $_SESSION['Theme'] = trim($_POST['Theme']); /*already set by session.inc but for completeness */ - $Theme = $_SESSION['Theme']; + $_SESSION['Style'] = trim($_POST['Style']); + $Theme = $_SESSION['Style']; $_SESSION['Language'] = trim($_POST['Language']); $_SESSION['PDFLanguage'] = $_POST['PDFLanguage']; include ('includes/LanguageSetup.php'); // After last changes in LanguageSetup.php, is it required to update? } } -echo '<form method="post" action="' . htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'UTF-8') . '">'; -echo '<div>'; -echo '<input type="hidden" name="FormID" value="' . $_SESSION['FormID'] . '" />'; -If (!isset($_POST['DisplayRecordsMax']) OR $_POST['DisplayRecordsMax']=='') { +$UserForm = $MainView->createForm(); +$UserForm->setAction(htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'UTF-8')); +$UserForm->addHiddenControl('RealName',$_SESSION['UsersRealName']); +//addControl($key,$tabindex,$type,$caption = null,$settings = null,$htmlclass = null,$row = null,$order = null,$dimensions = null) +$UserForm->addControl(1,-1,'static',_('User ID') . ':',array('text' => $_SESSION['UserID']),null,1); +$UserForm->addControl(2,-1,'static',_('User Name') . ':',array('text' => $_SESSION['UsersRealName']),null,1); +if (!isset($_POST['DisplayRecordsMax']) OR $_POST['DisplayRecordsMax']=='') { + $_POST['DisplayRecordsMax'] = $_SESSION['DefaultDisplayRecordsMax']; } - -echo '<table class="selection"> - <tr> - <td>' . _('User ID') . ':</td> - <td>' . $_SESSION['UserID'] . '</td> - </tr>'; - -echo '<tr> - <td>' . _('User Name') . ':</td> - <td>' . $_SESSION['UsersRealName'] . ' - <input type="hidden" name="RealName" value="'.$_SESSION['UsersRealName'].'" /></td></tr>'; - -echo '<tr> - <td>' . _('Maximum Number of Records to Display') . ':</td> - <td><input type="text" class="integer" required="required" title="'._('The input must be positive integer').'" name="DisplayRecordsMax" size="3" maxlength="3" value="' . $_POST['DisplayRecordsMax'] . '" /></td> - </tr>'; - - -echo '<tr> - <td>' . _('Language') . ':</td> - <td><select name="Language">'; - +//addControl($key,$tabindex,$type,$caption = null,$settings = null,$htmlclass = null,$row = null,$order = null,$dimensions = null) +$UserForm->addControl(3,1,'text',_('Maximum Number of Records to Display') . ':',array( 'value' => $_POST['DisplayRecordsMax'], + 'name' => 'DisplayRecordsMax', + 'size' => 3, + 'maxlength' => 3, + 'required' => true),'integer'); + +$UserForm->addControl(4,2,'select', _('Language') . ':',array('name' => 'Language')); if (!isset($_POST['Language'])){ $_POST['Language']=$_SESSION['Language']; } - +//addControlOption($key,$text,$value,$isSelected = null,$id = null) foreach ($LanguagesArray as $LanguageEntry => $LanguageName){ - if (isset($_POST['Language']) AND $_POST['Language'] == $LanguageEntry){ - echo '<option selected="selected" value="' . $LanguageEntry . '">' . $LanguageName['LanguageName'] . '</option>'; - } elseif (!isset($_POST['Language']) AND $LanguageEntry == $DefaultLanguage) { - echo '<option selected="selected" value="' . $LanguageEntry . '">' . $LanguageName['LanguageName'] . '</option>'; - } else { - echo '<option value="' . $LanguageEntry . '">' . $LanguageName['LanguageName'] . '</option>'; - } + //is this language selected? + $UserForm->addControlOption(4,$LanguageName['LanguageName'],$LanguageEntry,((isset($_POST['Language']) AND $_POST['Language'] == $LanguageEntry) || (!isset($_POST['Language']) AND $LanguageEntry == $DefaultLanguage))); } -echo '</select></td></tr>'; - -echo '<tr> - <td>' . _('Theme') . ':</td> - <td><select name="Theme">'; - -$ThemeDirectories = scandir('css/'); - - -foreach ($ThemeDirectories as $ThemeName) { - - if (is_dir('css/' . $ThemeName) AND $ThemeName != '.' AND $ThemeName != '..' AND $ThemeName != '.svn'){ - - if ($_SESSION['Theme'] == $ThemeName){ - echo '<option selected="selected" value="' . $ThemeName . '">' . $ThemeName . '</option>'; - } else { - echo '<option value="' . $ThemeName . '">' . $ThemeName . '</option>'; - } - } +//addControl($key,$tabindex,$type,$caption = null,$settings = null,$htmlclass = null,$row = null,$order = null,$dimensions = null) +$UserForm->addControl(5,3,'select',_('Theme') . ':',array('name' => 'Theme', 'childselect' => 'StylesID')); +$UserForm->addControl(6,4,'select',_('Styles') . ':',array('name' => 'Style', 'id' => 'StylesID', 'hasparent' => true)); +$allThemes = $MainView->getTemplates(true); +$styleOptions = array(); +$i = 0; +foreach ($allThemes as $aTheme) { + //addControlOption($key,$text,$value,$isSelected = null,$parentID = null,$id = null) + $UserForm->addControlOption(5,$aTheme['themename'],$aTheme['themefolder'],($MainView->getTheme() == 'themes/' . $aTheme['themefolder']),null,$i); + if (is_array($aTheme['styles'])) { + foreach($aTheme['styles'] as $key => $style) { + $UserForm->addControlOption(6,$style,$style,($MainView->getTheme() == 'themes/' . $aTheme['themefolder'] && $MainView->getStyle() == $style),$i); + } + } + $i++; } if (!isset($_POST['PasswordCheck'])) { @@ -168,53 +150,46 @@ if (!isset($_POST['Password'])) { $_POST['Password']=''; } -echo '</select></td></tr> - <tr> - <td>' . _('New Password') . ':</td> - <td><input type="password" name="Password" pattern="(?!^'.$_SESSION['UserID'].'$).{5,}" title="'._('Must be more than 5 characters and cannot be as same as userid').'" placeholder="'._('More than 5 characters').'" size="20" value="' . $_POST['Password'] . '" /></td> - </tr> - <tr> - <td>' . _('Confirm Password') . ':</td> - <td><input type="password" name="PasswordCheck" pattern="(?!^'.$_SESSION['UserID'].'$).{5,}" title="'._('Must be more than 5 characters and cannot be as same as userid').'" placeholder="'._('More than 5 characters').'" size="20" value="' . $_POST['PasswordCheck'] . '" /></td> - </tr> - <tr> - <td colspan="2" align="center"><i>' . _('If you leave the password boxes empty your password will not change') . '</i></td> - </tr> - <tr> - <td>' . _('Email') . ':</td>'; +$controlsettings['name'] = 'Password'; +$controlsettings['value'] = $_POST['Password']; +$controlsettings['pattern'] = '(?!^'.$_SESSION['UserID'].'$).{5,}'; +$controlsettings['title'] = _('Must be more than 5 characters and cannot be as same as userid'); +$controlsettings['placeholder'] = _('More than 5 characters'); +$controlsettings['size'] ='20'; + +//addControl($key,$tabindex,$type,$caption = null,$settings = null,$htmlclass = null,$row = null,$order = null,$dimensions = null) +$UserForm->addControl(7,5,'password',_('New Password') . ':',$controlsettings); +$controlsettings['name'] = 'PasswordCheck'; +$controlsettings['value'] = $_POST['PasswordCheck']; +$UserForm->addControl(8,6,'password',_('Confirm Password') . ':',$controlsettings); +$UserForm->addControl(9,-1,'content',null,array( 'align' => 'center', + 'text' => '<i>' . _('If you leave the password boxes empty your password will not change') . '</i>' + )); $sql = "SELECT email from www_users WHERE userid = '" . $_SESSION['UserID'] . "'"; $result = DB_query($sql,$db); $myrow = DB_fetch_array($result); if(!isset($_POST['email'])){ $_POST['email'] = $myrow['email']; } - -echo '<td><input type="email" name="email" size="40" value="' . $_POST['email'] . '" /></td> - </tr>'; - + +$UserForm->addControl(10,7,'email', _('Email') . ':',array( 'name' => 'email', + 'size' => 40, + 'value' => $_POST['email'])); + if (!isset($_POST['PDFLanguage'])){ $_POST['PDFLanguage']=$_SESSION['PDFLanguage']; } -echo '<tr> - <td>' . _('PDF Language Support') . ': </td> - <td><select name="PDFLanguage">'; +$UserForm->addControl(11,8,'select',_('PDF Language Support') . ':',array('name' => 'PDFLanguage')); -for($i=0;$i<count($PDFLanguages);$i++){ - if ($_POST['PDFLanguage']==$i){ - echo '<option selected="selected" value="' . $i .'">' . $PDFLanguages[$i] . '</option>'; - } else { - echo '<option value="' . $i .'">' . $PDFLanguages[$i]. '</option>'; - } +foreach($PDFLanguages as $i => $Lang){ + //addControlOption($key,$text,$value,$isSelected = null,$id = null) + $UserForm->addControlOption(11,$Lang,$i,($_POST['PDFLanguage']==$i)); } -echo '</select></td> - </tr> - </table> - <br /> - <div class="centre"><input type="submit" name="Modify" value="' . _('Modify') . '" /></div> - </div> - </form>'; -include('includes/footer.inc'); -?> \ No newline at end of file +$UserForm->addControl(12,9,'submit',_('Modify'),array('name' => 'Modify', + 'value' => _('Modify'))); +$UserForm->display(); +include('includes/footer_views.inc'); +?> Modified: trunk/api/api_session.inc =================================================================== --- trunk/api/api_session.inc 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/api/api_session.inc 2014-08-19 11:44:16 UTC (rev 6832) @@ -47,15 +47,23 @@ function CryptPass( $Password ) { - global $CryptFunction; - if ( $CryptFunction == 'sha1' ) { - return sha1($Password); - } elseif ( $CryptFunction == 'md5' ) { - return md5($Password); - } else { - return $Password; - } + if (PHP_VERSION_ID < 50500) { + $salt = base64_encode(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)); + $salt = str_replace('+', '.', $salt); + $hash = crypt($Password, '$2y$10$'.$salt.'$'); + } else { + $hash = password_hash($Password,PASSWORD_DEFAULT); + } + return $hash; } + + function VerifyPass($Password,$Hash) { + if(PHP_VERSION_ID < 50500) { + return (crypt($Password,$Hash)==$Hash); + } else { + return password_verify($Password,$Hash); + } + } // API wrapper for DB issues - no HTML output, AND remember any error message function api_DB_query( $sql, $db, $EMsg= '', $DMsg= '', $Transaction='', $TrapErrors=false ) Modified: trunk/config.distrib.php =================================================================== --- trunk/config.distrib.php 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/config.distrib.php 2014-08-19 11:44:16 UTC (rev 6832) @@ -70,11 +70,6 @@ //this can be left commented out //$SessionSavePath = '/tmp'; -// which encryption function should be used -//$CryptFunction = 'md5'; // MD5 Hash -$CryptFunction = 'sha1'; // SHA1 Hash -//$CryptFunction = ''; // Plain Text - //Setting to 12 or 24 determines the format of the clock display at the end of all screens $DefaultClock = 12; //$DefaultClock = 24; Modified: trunk/includes/UserLogin.php =================================================================== --- trunk/includes/UserLogin.php 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/includes/UserLogin.php 2014-08-19 11:44:16 UTC (rev 6832) @@ -41,16 +41,54 @@ } /* The SQL to get the user info must use the * syntax because the field name could change between versions if the fields are specifed directly then the sql fails and the db upgrade will fail */ $sql = "SELECT * - FROM www_users - WHERE www_users.userid='" . $Name . "' - AND (www_users.password='" . CryptPass($Password) . "' - OR www_users.password='" . $Password . "')"; + FROM www_users + WHERE www_users.userid='" . $Name . "'"; + $ErrMsg = _('Could not retrieve user details on login because'); $debug =1; + $continue = false; $Auth_Result = DB_query($sql, $db,$ErrMsg); + + if (DB_num_rows($Auth_Result) > 0) { + $myrow = DB_fetch_array($Auth_Result); + if (VerifyPass($Password,$myrow['password'])) { + $continue = true; + } elseif (isset($GLOBALS['CryptFunction'])) { + /*if the password stored in the DB was compiled the old way, + * the previous comparison will fail, + * try again with the old hashing algorithm, + * then re-hash the password using the new algorithm. + * The next version should not have $CryptFunction any more for new installs. + */ + switch ($GLOBALS['CryptFunction']) { + case 'sha1': + if ($myrow['password'] == sha1($Password)) { + $continue = true; + } + break; + case 'md5': + if ($myrow['password'] == md5($Password)) { + $continue = true; + } + break; + default: + if ($myrow['password'] == $Password) { + $continue = true; + } + } + if ($continue) { + $sql = "UPDATE www_users SET password = '".CryptPass($Password)."'" + . " WHERE userid = '".$Name."';"; + DB_query($sql,$db); + } + + } + } + + // Populate session variables with data base results - if (DB_num_rows($Auth_Result) > 0) { - $myrow = DB_fetch_array($Auth_Result); + if ($continue) { + if ($myrow['blocked']==1){ //the account is blocked return UL_BLOCKED; Modified: trunk/includes/session.inc =================================================================== --- trunk/includes/session.inc 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/includes/session.inc 2014-08-19 11:44:16 UTC (rev 6832) @@ -99,7 +99,7 @@ $Theme = (isset($_SESSION['Theme'])) ? $_SESSION['Theme'] : 'gel'; switch ($rc) { case UL_OK; //user logged in successfully - include($PathPrefix . 'includes/LanguageSetup.php'); //set up the language of the user + include($PathPrefix . 'includes/LanguageSetup.php'); //set up the language break; case UL_SHOWLOGIN: @@ -294,15 +294,23 @@ $debug = 0; //don't allow debug messages } function CryptPass( $Password ) { - global $CryptFunction; - if ( $CryptFunction == 'sha1' ) { - return sha1($Password); - } elseif ( $CryptFunction == 'md5' ) { - return md5($Password); - } else { - return $Password; - } + if (PHP_VERSION_ID < 50500) { + $salt = base64_encode(mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)); + $salt = str_replace('+', '.', $salt); + $hash = crypt($Password, '$2y$10$'.$salt.'$'); + } else { + $hash = password_hash($Password,PASSWORD_DEFAULT); + } + return $hash; } + + function VerifyPass($Password,$Hash) { + if(PHP_VERSION_ID < 50500) { + return (crypt($Password,$Hash)==$Hash); + } else { + return password_verify($Password,$Hash); + } + } if (sizeof($_POST) > 0 AND !isset($AllowAnyone)) { Modified: trunk/sql/mysql/country_sql/default.sql =================================================================== --- trunk/sql/mysql/country_sql/default.sql 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/sql/mysql/country_sql/default.sql 2014-08-19 11:44:16 UTC (rev 6832) @@ -4894,8 +4894,8 @@ -- Dumping data for table `www_users` -- -INSERT INTO `www_users` VALUES ('admin','f0f77a7f88e7c1e93ab4e316b4574c7843b00ea4','Demonstration user','','','','','ad...@we...','MEL',8,1,'2014-02-08 15:26:35','','A4','1,1,1,1,1,1,1,1,1,1,1,',0,50,'fluid','en_GB.utf8',3,0); -INSERT INTO `www_users` VALUES ('WEB0000017','f0f77a7f88e7c1e93ab4e316b4574c7843b00ea4','Phil Daintree','WEB0000017','','','+64(0)275567890','ph...@lo...','TOR',7,0,NULL,'WEB0000017','A4','0,0,0,0,0,0,0,0,0,0,0',0,30,'silverwolf','en_GB.utf8',0,0); +INSERT INTO `www_users` VALUES ('admin','$2y$10$dXQ1ehIVzIS8i9G3sK34ROkJCxHO.O0pRlgmRLj.YL2rYH5DF45Ri','Demonstration user','','','','','ad...@we...','MEL',8,1,'2014-02-08 15:26:35','','A4','1,1,1,1,1,1,1,1,1,1,1,',0,50,'fluid','en_GB.utf8',3,0); +INSERT INTO `www_users` VALUES ('WEB0000017','$2y$10$dXQ1ehIVzIS8i9G3sK34ROkJCxHO.O0pRlgmRLj.YL2rYH5DF45Ri','Phil Daintree','WEB0000017','','','+64(0)275567890','ph...@lo...','TOR',7,0,NULL,'WEB0000017','A4','0,0,0,0,0,0,0,0,0,0,0',0,30,'silverwolf','en_GB.utf8',0,0); -- -- Dumping data for table `edi_orders_segs` Modified: trunk/sql/mysql/country_sql/demo.sql =================================================================== --- trunk/sql/mysql/country_sql/demo.sql 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/sql/mysql/country_sql/demo.sql 2014-08-19 11:44:16 UTC (rev 6832) @@ -9191,8 +9191,8 @@ -- Dumping data for table `www_users` -- -INSERT INTO `www_users` VALUES ('admin','f0f77a7f88e7c1e93ab4e316b4574c7843b00ea4','Demonstration user','','','','','ad...@we...','MEL',8,1,'2014-02-08 15:26:35','','A4','1,1,1,1,1,1,1,1,1,1,1,',0,50,'fluid','en_GB.utf8',3,0); -INSERT INTO `www_users` VALUES ('WEB0000017','f0f77a7f88e7c1e93ab4e316b4574c7843b00ea4','Phil Daintree','WEB0000017','','','+64(0)275567890','ph...@lo...','TOR',7,0,NULL,'WEB0000017','A4','0,0,0,0,0,0,0,0,0,0,0',0,30,'silverwolf','en_GB.utf8',0,0); +INSERT INTO `www_users` VALUES ('admin','$2y$10$dXQ1ehIVzIS8i9G3sK34ROkJCxHO.O0pRlgmRLj.YL2rYH5DF45Ri','Demonstration user','','','','','ad...@we...','MEL',8,1,'2014-02-08 15:26:35','','A4','1,1,1,1,1,1,1,1,1,1,1,',0,50,'fluid','en_GB.utf8',3,0); +INSERT INTO `www_users` VALUES ('WEB0000017','$2y$10$dXQ1ehIVzIS8i9G3sK34ROkJCxHO.O0pRlgmRLj.YL2rYH5DF45Ri','Phil Daintree','WEB0000017','','','+64(0)275567890','ph...@lo...','TOR',7,0,NULL,'WEB0000017','A4','0,0,0,0,0,0,0,0,0,0,0',0,30,'silverwolf','en_GB.utf8',0,0); /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; Modified: trunk/sql/mysql/country_sql/weberpchina.sql =================================================================== --- trunk/sql/mysql/country_sql/weberpchina.sql 2014-08-19 07:53:01 UTC (rev 6831) +++ trunk/sql/mysql/country_sql/weberpchina.sql 2014-08-19 11:44:16 UTC (rev 6832) @@ -4813,7 +4813,7 @@ -- Dumping data for table weberpcn.www_users: ~1 rows (approximately) /*!40000 ALTER TABLE `www_users` DISABLE KEYS */; INSERT INTO `www_users` (`userid`, `password`, `realname`, `customerid`, `supplierid`, `salesman`, `phone`, `email`, `defaultlocation`, `fullaccess`, `cancreatetender`, `lastvisitdate`, `branchcode`, `pagesize`, `modulesallowed`, `blocked`, `displayrecordsmax`, `theme`, `language`, `pdflanguage`, `department`) VALUES - ('admin', 'f865b53623b121fd34ee5426c792e5c33af8c227', '张三', '', '', '', '', 'ad...@we...', 'MEL', 8, 1, '2013-11-18 07:50:02', '', 'A4', '1,1,1,1,1,1,1,1,1,1,1,', 0, 50, 'fluid', 'zh_CN.utf8', 2, 0); + ('admin', '$2y$10$e7xelMwFyXZd.Ap5ssqDhutlfNIY3yvckOYFb9EP0vSGG.HkuCVQm', '张三', '', '', '', '', 'ad...@we...', 'MEL', 8, 1, '2013-11-18 07:50:02', '', 'A4', '1,1,1,1,1,1,1,1,1,1,1,', 0, 50, 'fluid', 'zh_CN.utf8', 2, 0); /*!40000 ALTER TABLE `www_users` ENABLE KEYS */; /*!40014 SET FOREIGN_KEY_CHECKS=1 */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; |