Sindbad~EG File Manager
# -*- coding: utf-8 -*-
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2018 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import configparser
import os
import re
from itertools import groupby, filterfalse
from collections import namedtuple
import locale
class WebConfigParsingError(Exception):
def __init__(self, message):
self.message = message
class WebConfigMissing(Exception):
def __init__(self, message):
self.message = message
SECHEAD = 'asection'
def load(path, case_sensitive=False, ignore_bad_encoding=False):
config = configparser.ConfigParser(allow_no_value=True,
interpolation=None,
strict=False)
if case_sensitive:
config.optionxform = str
if ignore_bad_encoding:
with open(path, 'rb') as f:
raw = f.read().decode(locale.getpreferredencoding(), 'replace')
else:
with open(path, 'r') as f:
raw = f.read()
config.read_string(f'[{SECHEAD}]\n' + raw, source=path)
return dict(config.items(section=SECHEAD))
def load_fast(path, case_sensitive=False):
data = dict()
with open(path, 'r', errors='surrogateescape') as f:
for line in f.read().splitlines():
try:
key, value = line.split('=', 1)
data[key.strip()] = value.strip()
except ValueError: # skip broken lines
pass
return data
cache = {}
def load_once(path, ignore_errors = False):
"""
Read ini file once (cached) and return its content as dict
"""
try:
res = cache[path]
except KeyError:
try:
res = cache[path] = load(path)
except (IOError, configparser.Error):
if not ignore_errors:
raise
res = cache[path] = {}
return res
def change_settings(dict, path, tmp_path=None):
if not tmp_path:
tmp_path = path+".tmp"
fin = open(path, 'r')
fout = open(tmp_path, 'w')
used_keys = []
for line in fin:
l = line.strip()
if l and not l.startswith('#'):
key, value = l.split('=', 1)
key = key.strip()
if key in dict:
fout.write(key+'='+str(dict[key])+'\n')
used_keys.append(key)
continue
fout.write(line)
fin.close()
for key in list(dict.keys()):
if key not in used_keys:
fout.write(key+'='+str(dict[key])+'\n')
fout.close()
os.rename(tmp_path, path)
def nginx_conf_parser(conf_file):
if not os.path.isfile(conf_file):
raise WebConfigMissing('File does not exists %s' % conf_file)
with open(conf_file, 'r') as f:
dirty_data = f.read().splitlines()
data_stripped = [r.strip().rstrip(';') for r in dirty_data]
data_pure = filterfalse(lambda r: r == '' or r.startswith('#'), data_stripped)
data_grouped = (group for _, group in groupby(data_pure, lambda x: x.strip() == "server") if not _)
vhosts = []
for server_group in data_grouped:
server_info = {'server_name': '', 'document_root': '', 'ssl': None}
try:
for row in server_group:
if row.startswith('root '):
server_info['document_root'] = row.replace('root ', '').strip()
elif row.startswith('server_name '):
server_info['server_name'] = row.replace('server_name ', '').split(' ')[0].strip()
elif row.startswith('listen '):
server_info['ssl'] = 'ssl' in row
except IndexError:
raise WebConfigParsingError('Bad file format in %s' % conf_file)
else:
vhosts.append(server_info)
return vhosts
def apache_conf_parser(conf_file):
if not os.path.isfile(conf_file):
raise WebConfigMissing('File does not exists %s' % conf_file)
conf_data = list()
f = open(conf_file, 'r')
data_all = f.readlines()
f.close()
data = [i for i in data_all if re.search('^((?!#).)*$', i)]
ID = 0
enable = False
result = {}
vhost = []
while len(data) > 0:
out = data.pop(0)
if "<VirtualHost" in out:
ip_port = out.split()[1]
port = '0'
try:
ip, port = ip_port.split(':')
port = port.replace('>', '')
except ValueError:
ip = ip_port
vhost.append(ip)
vhost.append(port)
enable = True
continue
if "</VirtualHost>" in out:
result[ID] = vhost
ID+=1
enable = False
vhost = []
continue
if enable:
vhost.append(out)
continue
for i in result:
# result[i][0] is an IP
# result[i][1] is a port
data = {
'user' : None,
'server_name' : '',
'document_root' : '',
'server_alias' : None,
'port' : int(result[i][1]),
'ssl' : False,
}
for line in result[i]:
if "ServerName" in line:
data['server_name'] = line.split()[1].strip().replace('www.', '')
continue
if "DocumentRoot" in line:
data['document_root'] = line.split()[1].strip()
continue
if "ServerAlias" in line:
data['server_alias'] = ','.join(str(n) for n in line.split()[1:])
continue
if "SuexecUserGroup" in line:
data['user'] = line.split()[1].strip()
if "SSLEngine" in line:
data['ssl'] = line.split()[1].strip().lower() == 'on'
conf_data.append(data)
return conf_data
PamLVECfg = namedtuple('PamLVECfg', ['min_uid', 'cagefs_enabled', 'groups'])
def parse_pam_lve_config(configfile):
"""
Parse string like:
"session required pam_lve.so 500 1 group1,group2"
:param configfile: path to config file to parse
:type configfile: str
:return: PamLVECfg instance when pam_lve configuratiom is found, None otherwise
:rtype: namedtuple
:raises: IOError, ValueError
"""
with open(configfile, 'r') as f:
for line in f:
if line.startswith('#'):
continue
s = line.split()
l = len(s)
if l >= 3 and s[2] == 'pam_lve.so':
# parse config string taking pam_lve defaults into account
min_uid = int(s[3]) if l >= 4 else 500
cagefs_enabled = bool(int(s[4])) if l >= 5 else False
groups = s[5].split(',') if l >= 6 else ['wheel']
return PamLVECfg(min_uid, cagefs_enabled, groups)
# pam_lve line is not found in config file
return None
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists