Mini Shell
Direktori : /usr/share/cagefs/ |
|
Current File : //usr/share/cagefs/phpinivalidator.py |
#!/opt/cloudlinux/venv/bin/python3 -bb
# -*- coding: utf-8 -*-
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
"""
Module to validate the configuration file alt_phpXX.cfg
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import *
import re
import os
ALTPHPVER_PATTERN = re.compile(r'alt_php(\d)(\d)\.cfg')
def get_php_ver(input_phpini_path):
"""
function to get the version of the php file name alt_phpXX.cfg
for example: 'alt_php55.cfg' => '5.5'
"""
php_ver_searched = ALTPHPVER_PATTERN.search(os.path.basename(input_phpini_path))
if php_ver_searched:
return '.'.join(php_ver_searched.group(1, 2))
class PHPINIvalidator(object):
DIRECTIVE_PATTERN = re.compile(r'(^Directive|Type|Range|Remark)\s*=\s*(.*\S)\s*$')
CUSTOM_OPTIONS_DIRECTIVE_PATTERN = re.compile(r'^([a-zA-Z0-9_.]+)\s*=\s*([^;="]+[^;=" \t]|".+"|[^;="])\s*(;.*)?$')
BOOLEAN_VARIANTS = ('On', 'Off', '0', '1', 'True', 'False')
def __init__(self, phpconf_path='/etc/cl.selector/php.conf'):
self.phpconf_path = phpconf_path
self._phpconf_data = self._load_phpconf(self.phpconf_path)
# List with unknown options:
self.unknown_options = []
# List options:
self.invalid_values_options = []
# List of invalid options (for example, options without values)
self.invalid_options = []
def _load_phpconf(self, phpconf_path):
"""
Load reference data.
Gets a dictionary of the form; example:
{'upload_max_filesize': {'Default':'2M', 'Type':'list', 'Range'; '2M,4M,8M,16M,32M,64M,128M,256M,512M,1G'}
"""
phpconf_dict = {}
directive_title = None
phpconf = open(phpconf_path)
for phpconf_line in phpconf:
if phpconf_line.startswith('#'):
continue
searched = self.DIRECTIVE_PATTERN.search(phpconf_line.rstrip())
if not searched:
continue
directive_name, directive_val = searched.group(1, 2)
if directive_name == 'Directive':
directive_title = directive_val
phpconf_dict[directive_title] = dict()
else:
phpconf_dict[directive_title][directive_name] = directive_val
phpconf.close()
return phpconf_dict
# Use only full php_ver (e.g 5.4.11 instead of 5.4)
def validate(self, input_phpini_lines, php_ver):
output_phpini_lines = []
# Clear lists of bad options
self.unknown_options = []
self.invalid_values_options = []
self.invalid_options = []
for input_phpini_line in input_phpini_lines:
output_phpini_line = input_phpini_line
if input_phpini_line.startswith(';'):
output_phpini_lines.append(output_phpini_line)
continue
try:
input_phpini_line1 = input_phpini_line.strip()
if input_phpini_line1.endswith('='):
input_phpini_line1 += '0'
directive_name, directive_val = self.CUSTOM_OPTIONS_DIRECTIVE_PATTERN.search(input_phpini_line1).group(1, 2)
is_valid_directive, is_valid_value = self._validate_directive_val(directive_name=directive_name, directive_val=directive_val, php_ver=php_ver)
if not is_valid_directive:
self.unknown_options.append(input_phpini_line.strip())
else:
# Directive is valid, check value
if not is_valid_value:
self.invalid_values_options.append(input_phpini_line.strip())
except AttributeError:
is_valid_directive = False
is_valid_value = False
self.invalid_options.append(input_phpini_line.strip())
if not (is_valid_directive and is_valid_value):
output_phpini_line = ';' + input_phpini_line
output_phpini_lines.append(output_phpini_line)
return output_phpini_lines
def _validate_directive_val(self, directive_name, directive_val, php_ver):
"""
Validates directive for supplied PHP version
:param directive_name: Directive name
:param directive_val: Directive name
:param php_ver: PHP version (3 digits) to check directive
:return: Tuple (is_valid_directive, is_valid_value) - boolean flags validity of directive and value
"""
directive_data_dict = self._phpconf_data.get(directive_name)
if not directive_data_dict:
return False, False
directive_data_type = directive_data_dict['Type']
remark = directive_data_dict.get('Remark')
if remark:
# Remark present
if remark.startswith('>') or remark.startswith('<'):
remark_znak = remark[0]
remark_ver = remark[1:]
if remark_znak == '<':
if php_ver.split('.') > remark_ver.split('.'):
# version mismatch
return False, False
elif remark_znak == '>':
# return php_ver.split('.') > remark_ver.split('.'), False
if php_ver.split('.') < remark_ver.split('.'):
# version mismatch
return False, False
else:
# Remark: = xx.yy.zzz or Remark: = xx.yy
# Form 2-digit versions from remark and checking alt-php version
remark_ver_parts = remark.split('.')
remark_ver_2digit = '%s.%s' % (remark_ver_parts[0], remark_ver_parts[1])
php_ver_parts = php_ver.split('.')
php_ver_2digit = '%s.%s' % (php_ver_parts[0], php_ver_parts[1])
if remark_ver_2digit != php_ver_2digit:
# Invalid directive for supplied PHP version
return False, False
if directive_name not in self._phpconf_data:
# No such directive
return False, False
if directive_data_type == 'bool':
if directive_val not in self.BOOLEAN_VARIANTS:
# directive value is boolean (by php.conf), but directive_val not boolean
return True, False
elif directive_data_type == 'list':
if directive_val not in directive_data_dict['Range'].split(','):
# directive value is not from php.conf list
return True, False
return True, True
Zerion Mini Shell 1.0