2017-10-26 01:56:09 -05:00
<? php
/**
* Php.php
*
* Check that various PHP modules and functions exist.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2017 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Validations ;
use LibreNMS\Config ;
2017-11-23 02:29:10 -06:00
use LibreNMS\ValidationResult ;
2017-10-26 01:56:09 -05:00
use LibreNMS\Validator ;
2018-02-27 09:57:20 -06:00
class Php extends BaseValidation
2017-10-26 01:56:09 -05:00
{
2020-04-24 11:04:36 +02:00
const PHP_MIN_VERSION = '7.2.5' ;
const PHP_MIN_VERSION_DATE = 'May, 2020' ;
const PHP_RECOMMENDED_VERSION = '7.3' ;
2017-10-26 01:56:09 -05:00
/**
* Validate this module.
* To return ValidationResults, call ok, warn, fail, or result methods on the $validator
*
* @param Validator $validator
*/
public function validate ( Validator $validator )
{
$this -> checkVersion ( $validator );
2017-11-23 02:29:10 -06:00
$this -> checkSessionDirWritable ( $validator );
2017-10-26 01:56:09 -05:00
$this -> checkExtensions ( $validator );
$this -> checkFunctions ( $validator );
$this -> checkTimezone ( $validator );
}
private function checkVersion ( Validator $validator )
{
2017-11-23 02:29:10 -06:00
// if update is not set to false and version is min or newer
2020-04-24 11:04:36 +02:00
if ( Config :: get ( 'update' ) && version_compare ( PHP_VERSION , self :: PHP_MIN_VERSION , '<' )) {
$validator -> warn ( "PHP version " . self :: PHP_MIN_VERSION . " is the minimum supported version as of " . self :: PHP_MIN_VERSION_DATE . ". We recommend you update PHP to a supported version (" . self :: PHP_RECOMMENDED_VERSION . " suggested) to continue to receive updates. If you do not update PHP, LibreNMS will continue to function but stop receiving bug fixes and updates." );
2017-10-26 01:56:09 -05:00
}
}
2017-11-23 02:29:10 -06:00
private function checkSessionDirWritable ( Validator $validator )
{
$path = session_save_path () === '' ? '/tmp' : session_save_path ();
if ( ! is_writable ( $path )) {
$result = ValidationResult :: fail ( "The session directory ( $path ) is not writable." );
$group_id = filegroup ( $path );
if ( $group_id !== 0 && check_file_permissions ( $path , '060' )) {
// don't suggest adding users to the root group or a group that doesn't have write permission.
if ( function_exists ( 'posix_getgrgid' )) {
$group_info = posix_getgrgid ( $group_id );
$group = $group_info [ 'name' ];
$user = $validator -> getUsername ();
$result -> setFix ( "usermod -a -G $group $user " );
}
}
$validator -> result ( $result );
}
}
2017-10-26 01:56:09 -05:00
private function checkExtensions ( Validator $validator )
{
2020-03-22 19:02:07 +00:00
$required_modules = [ 'mysqlnd' , 'mbstring' , 'pcre' , 'curl' , 'session' , 'xml' , 'gd' , 'sockets' , 'dom' ];
2017-11-28 21:19:06 -06:00
if ( Config :: get ( 'distributed_poller' )) {
$required_modules [] = 'memcached' ;
}
2017-10-26 01:56:09 -05:00
foreach ( $required_modules as $extension ) {
if ( ! extension_loaded ( $extension )) {
$validator -> fail ( "Missing PHP extension: $extension " , "Please install $extension " );
2017-11-07 14:09:49 -06:00
} elseif ( shell_exec ( "php -r \" var_export(extension_loaded(' $extension ')); \" " ) == 'false' ) {
$validator -> fail ( "Missing CLI PHP extension: $extension " , "Please install $extension " );
2017-10-26 01:56:09 -05:00
}
}
2017-11-10 09:20:47 -06:00
$suggested_extensions = array ( 'posix' => 'php-process' );
foreach ( $suggested_extensions as $extension => $packages ) {
if ( ! extension_loaded ( $extension )) {
$validator -> warn ( "Missing optional PHP extension: $extension " , "It is suggested you install $packages or the one that matches your php version" );
}
}
2017-10-26 01:56:09 -05:00
}
private function checkFunctions ( Validator $validator )
{
$disabled_functions = explode ( ',' , ini_get ( 'disable_functions' ));
$required_functions = array (
'exec' ,
'passthru' ,
'shell_exec' ,
'escapeshellarg' ,
'escapeshellcmd' ,
'proc_close' ,
'proc_open' ,
'popen'
);
foreach ( $required_functions as $function ) {
if ( in_array ( $function , $disabled_functions )) {
$validator -> fail ( " $function is disabled in php.ini" );
}
}
if ( ! function_exists ( 'openssl_random_pseudo_bytes' )) {
$validator -> warn ( "openssl_random_pseudo_bytes is not being used for user password hashing. This is a recommended function (https://secure.php.net/openssl_random_pseudo_bytes)" );
if ( ! is_readable ( '/dev/urandom' )) {
$validator -> warn ( "It also looks like we can't use /dev/urandom for user password hashing. We will fall back to generating our own hash - be warned" );
}
}
}
private function checkTimezone ( Validator $validator )
{
2017-11-07 05:22:12 -06:00
// collect data
2017-10-26 01:56:09 -05:00
$ini_tz = ini_get ( 'date.timezone' );
$sh_tz = rtrim ( shell_exec ( 'date +%Z' ));
$php_tz = date ( 'T' );
2017-11-07 05:22:12 -06:00
$php_cli_tz = rtrim ( shell_exec ( 'php -r "echo date(\'T\');"' ));
2017-10-26 01:56:09 -05:00
if ( empty ( $ini_tz )) {
2017-11-07 05:22:12 -06:00
// make sure timezone is set
2017-10-26 01:56:09 -05:00
$validator -> fail (
'You have no timezone set for php.' ,
'http://php.net/manual/en/datetime.configuration.php#ini.date.timezone'
);
} elseif ( $sh_tz !== $php_tz ) {
2017-11-07 05:22:12 -06:00
// check if system timezone matches the timezone of the current running php
2020-04-21 07:30:19 -05:00
$ini_file = php_ini_loaded_file ();
2017-11-07 05:22:12 -06:00
$validator -> fail (
"You have a different system timezone ( $sh_tz ) than the php configured timezone ( $php_tz )" ,
2020-04-21 07:30:19 -05:00
"Please correct either your system timezone or your timezone set in $ini_file ."
2017-11-07 05:22:12 -06:00
);
} elseif ( $php_tz !== $php_cli_tz ) {
// check if web and cli timezones match (this does nothing if validate.php is run on cli)
// some distros have different php.ini for cli and the web server
if ( $sh_tz !== $php_cli_tz ) {
2020-04-21 07:30:19 -05:00
$ini_file = rtrim ( shell_exec ( 'php -r "echo php_ini_loaded_file();"' ));
2017-11-07 05:22:12 -06:00
$validator -> fail (
"The CLI php.ini ( $php_cli_tz ) timezone is different than your system's timezone ( $sh_tz )" ,
2020-04-21 07:30:19 -05:00
"Edit your CLI ini file $ini_file and set the correct timezone ( $sh_tz )."
2017-11-07 05:22:12 -06:00
);
}
2017-10-26 01:56:09 -05:00
}
}
}