master
parent cc9288b31b
commit 5ec8b4989e

@ -1,723 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import os
import stat
import re
from os import path
from calculate.core.server.core_interfaces import MethodsInterface
from calculate.lib.utils.files import (makeDirectory, removeDir, tar_directory,
FilePermission, find, listDirectory,
FilesError, process, readFileEx,
readFile, pathJoin, FindFileType)
from calculate.lib.utils.content import FileOwnersRestricted, ContentsStorage
from calculate.lib.utils.portage import getInstalledAtom, makeCfgName
from calculate.lib.configparser import ConfigParserCaseSens
from calculate.lib.cl_template import Template
from calculate.lib.utils.accounts import Passwd, Group, Shadow
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from variables.action import Actions
import tarfile
import shutil
import glob
from itertools import chain
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class BackupError(Exception):
"""
Исключение вызванное во время резервного копирования настроек
"""
class Backup(MethodsInterface):
"""
Выполнение резервного копирования настроек
"""
def init(self):
self.apply_files = set()
self.unlink_autorun = set()
self.uid_map = {}
self.gid_map = {}
def prepare_backup(self, dn, rootname):
makeDirectory(path.join(dn, rootname))
return True
def remove_directory(self, dn):
removeDir(dn)
return True
def backup_user_changed(self, owner, dn_root):
"""
Сохранить конфигурационные файлы изменённые пользователем
:param owner:
:param dn_root:
:return:
"""
for fn in owner.get_md5_failed(lambda x: x.startswith('/etc')):
self.backup_file(fn, dn_root)
return True
def prepare_contents(self, dn, contents_file, rootname):
dn_root = path.join(dn, rootname)
fo = FileOwnersRestricted(
"/", ["/%s" % x for x in find(path.join(dn, rootname),
fullpath=False)] + ["/etc"])
self.backup_user_changed(fo, dn_root)
cs = ContentsStorage(contents_file, fo)
cs.keep(dn_root, dn_root)
return True
def create_archive(self, dn, archfile):
arch_dn = path.dirname(archfile)
if not path.exists(arch_dn):
makeDirectory(arch_dn)
os.chmod(arch_dn, FilePermission.UserAll)
tar_directory(dn, archfile)
return True
def open_archive(self, dn, archfile):
makeDirectory(dn)
with tarfile.open(archfile, 'r:bz2') as f:
f.extractall(dn)
return True
def restore_configs(self, archfile, dn, contents_name, root_name):
"""
Восстановить все файлы настроек
:param archfile:
:param dn:
:return:
"""
dirs_data = {}
used_dirs = set()
_gid = lambda x: self.gid_map.get(x, x)
_uid = lambda x: self.uid_map.get(x, x)
with tarfile.open(archfile, 'r:bz2') as f:
try:
# исключить из переноса файлы, которые принадлежат пакетам,
# которые не установлены в системе
contents = f.extractfile(f.getmember(contents_name))
pkg_file = [x.split()[:3:2] for x in contents]
not_installed_files = [
x for x in pkg_file
if not any(getInstalledAtom(x[0].partition(":")[0]))]
skip_packages = sorted(list(
set([x[0] for x in not_installed_files])))
if skip_packages:
self.printWARNING(
_("Settings ignored for following packages: %s") %
", ".join(x.partition(":")[0] for x in skip_packages))
not_installed_files = [x[1] for x in not_installed_files]
except KeyError:
raise BackupError(_("CONTENTS file not found"))
for ti in (x for x in f if x.name.startswith("%s/" % root_name)):
if ti.name[4:] in not_installed_files:
continue
if ti.issym() and not path.exists(ti.linkpath):
continue
if ti.name[5:]:
fn_system = path.join(dn, ti.path[5:])
if ti.isdir():
dirs_data[fn_system] = (ti.mode, _uid(ti.uid),
_gid(ti.gid))
continue
dirs_list = fn_system.split('/')
for i in range(2, len(dirs_list)):
used_dirs.add("/".join(dirs_list[:i]))
if path.lexists(fn_system):
stat_system = os.lstat(fn_system)
if ti.issym():
if stat.S_ISLNK(stat_system.st_mode):
system_link = os.readlink(fn_system)
if system_link == ti.linkpath:
continue
else:
if (stat.S_IMODE(stat_system.st_mode) == ti.mode and
stat_system.st_uid == _uid(ti.uid) and
stat_system.st_gid == _gid(ti.gid)):
data_system = readFile(fn_system)
extr_file = f.extractfile(ti)
if extr_file:
data_ti = extr_file.read()
if self.is_equal_files(data_system,
data_ti):
continue
ti.name = ti.name[5:]
f.extract(ti, dn)
os.chown(fn_system, _uid(ti.uid), _gid(ti.gid))
if ti.isfile() or ti.issym():
# если симлинк в списке предварительного удаления
# то исключаем его из списка изменённых файлов
if fn_system in self.unlink_autorun:
self.unlink_autorun.remove(fn_system)
else:
self.apply_files.add(fn_system)
# восстановление прав у каталогов, конфиги в которых должны были
# восстанавливаться
for dn_name in sorted(used_dirs):
if dn_name in dirs_data:
dn_mode, dn_uid, dn_gid = dirs_data[dn_name]
if path.lexists(dn_name):
stat_system = os.lstat(dn_name)
if (stat.S_IMODE(stat_system.st_mode) != dn_mode or
stat_system.st_uid != dn_uid or
stat_system.st_gid != dn_gid):
os.chmod(dn_name, dn_mode)
os.chown(dn_name, dn_uid, dn_gid)
return True
def sava_ini(self, section, key, val):
ini = ConfigParserCaseSens(strict=False)
ini.read(self.clVars.Get('cl_backup_ini_env'), encoding="utf-8")
if not ini.has_section(section):
ini.add_section(section)
ini[section][key] = str(val)
ini["backup"]["version"] = self.clVars.Get('cl_ver')
with open(self.clVars.Get('cl_backup_ini_env'), 'w') as f:
ini.write(f)
return True
def load_ini(self, section, key):
ini = ConfigParserCaseSens(strict=False)
ini.read(self.clVars.Get('cl_backup_ini_env'), encoding="utf-8")
return ini.get(section, key, fallback="")
def save_initd(self, dn, root_name):
"""
Сохранить список init.d
:param dn:
:param root_name:
:return:
"""
self.sava_ini("backup", "init",
','.join(listDirectory('/etc/init.d', fullPath=False)))
dn_root = path.join(dn, root_name)
for dn in ('/etc/runlevels/sysinit',
'/etc/runlevels/default',
'/etc/runlevels/boot'):
try:
dn_backup = pathJoin(dn_root, dn)
if not path.exists(dn_backup):
makeDirectory(dn_backup)
for fn in listDirectory(dn, fullPath=True):
if path.islink(fn):
link = os.readlink(fn)
symname = pathJoin(dn_root, fn)
if not path.lexists(symname):
os.symlink(link, symname)
except (OSError, IOError) as e:
raise BackupError(_("Failed to enable service at startup") +
(_(": %s") % (str(e))))
return True
def make_directory_sync(self, base_dn, dn, prefix="/"):
"""
Создать директорию и сохранить права из prefix
:param dn:
:param prefix:
:return:
"""
if not path.exists(dn):
self.make_directory_sync(base_dn, path.dirname(dn), prefix)
rel_dn = path.relpath(dn, base_dn)
system_dn = path.join(prefix, rel_dn)
system_dn_stat = os.lstat(system_dn)
if not makeDirectory(dn):
raise BackupError(_("Failed to create directory %s") % dn)
os.chown(dn, system_dn_stat.st_uid, system_dn_stat.st_gid)
os.chmod(dn, stat.S_IMODE(system_dn_stat.st_mode))
def backup_file(self, source_fn, target_dn, prefix="/"):
"""
Сделать резервную копию указанного файла
:param source_fn:
:param target_dn:
:return:
"""
target_fn = path.join(target_dn, path.relpath(source_fn, prefix))
source_stat = os.lstat(source_fn)
target_base_dn = path.dirname(target_fn)
self.make_directory_sync(target_dn, target_base_dn, prefix=prefix)
if stat.S_ISLNK(source_stat.st_mode):
source_link = os.readlink(source_fn)
os.symlink(source_link, target_fn)
elif stat.S_ISREG(source_stat.st_mode):
shutil.copy2(source_fn, target_fn)
os.chown(target_fn, source_stat.st_uid, source_stat.st_gid)
return True
def backup_marked(self, source_dn, target_dn, subdn, root_name):
"""
Сохранить файлы из указанного каталога, отмеченного комментариями
выполнения шаблонов
:return:
"""
source_etc_dn = path.join(source_dn, subdn)
root_dn = path.join(target_dn, root_name)
reCfg = re.compile('._cfg\d{4}_')
try:
for fn in find(source_etc_dn, filetype=FindFileType.RegularFile):
if (not reCfg.search(fn) and
" Modified Calculate" in readFileEx(fn,
headbyte=300)):
self.backup_file(fn, root_dn, prefix=source_dn)
except (OSError, IOError) as e:
raise BackupError(_("Failed to backup configuration files that "
"were modified by templates") +
(_(": %s") % (str(e))))
return True
def clear_autorun(self):
"""
Удалить все файлы из автозапуска, которые ссылаются на файлы из списка
init.d
:return:
"""
files = ["/etc/init.d/%s" % x.strip()
for x in self.load_ini("backup", "init").split(',')]
for dn in ('/etc/runlevels/sysinit',
'/etc/runlevels/default',
'/etc/runlevels/boot'):
for fn in listDirectory(dn, fullPath=True):
if path.islink(fn) and os.readlink(fn) in files:
os.unlink(fn)
self.unlink_autorun.add(fn)
return True
def restore_contents(self, contentsfile, dn):
cs = ContentsStorage(contentsfile)
cs.restore(dn, files=self.apply_files)
return True
def set_service_action(self):
self.clVars.Set('core.cl_backup_action', Actions.Service, force=True)
return True
nm_name = "NetworkManager"
nm_config = "/etc/NetworkManager"
nm_connections = path.join(nm_config, "system-connections")
def _do_service(self, service, action):
"""
Выполнить действие с сервисом (restart, start, stop, zap)
:param service:
:param action:
:return:
"""
actions = {
'restart': _("Failed to restart {name} service"),
'start': _("Failed to start {name} service"),
'stop': _("Failed to stop {name} service"),
'zap': _("Failed to zap {name} service"),
'status': _("Failed to get status of {name} service")
}
try:
p = process(service, action)
if p.failed():
data = p.readerr().strip()
if ("has started, but is inactive" not in data and
"will start when" not in data):
for line in data.split('\n'):
self.printERROR(line)
raise BackupError(actions.get(action, action).format(
name=path.basename(service)))
except FilesError:
self.printERROR(actions.get(action, action).format(
name=path.basename(service)))
raise
return True
def stop_net_services(self):
"""
Остановить все сетевые службы (и NM и openrc)
:return:
"""
self._do_service("/etc/init.d/netmount", "zap")
for fn in chain(["/etc/init.d/%s" % self.nm_name],
glob.glob('/etc/init.d/net.*')):
if fn.endswith('.lo') or not path.exists(fn):
continue
self._do_service(fn, "stop")
return True
def unlink_openrc_net_services(self, files):
"""
Удалить сетевые сервисы openrc сервисы openrc
:return:
"""
for fn in glob.glob('/etc/init.d/net.*'):
if fn.endswith('.lo') or not path.exists(fn) or fn in files:
continue
try:
os.unlink(fn)
self.apply_files.add(fn)
except OSError as e:
self.printERROR(_("Failed to remove %s service"),
path.basename(fn))
self.printERROR(str(e))
return True
def is_networkmanager_backup(self, backup_path):
"""
Проверить сетевой менеджер в резервной копии
:param backup_path:
:return:
"""
return path.lexists(path.join(
backup_path, "root/etc/runlevels/default/%s" % self.nm_name))
def is_networkmanager_system(self):
"""
Проверить сетевой менеджер в текущей системе
:return:
"""
return path.lexists("/etc/runlevels/default/%s" % self.nm_name)
def restore_openrc_net_initd(self, files):
"""
Восстановить сервисы net.* и запустить их
:return:
"""
for fn in files:
if not path.exists(fn):
os.symlink("/etc/init.d/net.lo", fn)
self.apply_files.add(fn)
self._do_service(fn, "start")
return True
def restore_files(self, backup_path, files, notapply=False):
"""
Восстановить указанные файлы из backup/root
:param backup_path:
:param files: список файлов (поддерживаются глобальные символы)
:return:
"""
len_source_prefix = len(path.join(backup_path, "root"))
_gid = lambda x: self.gid_map.get(x, x)
_uid = lambda x: self.uid_map.get(x, x)
for source in chain(*[glob.glob(pathJoin(backup_path, "root", x))
for x in files]):
dest = source[len_source_prefix:]
if path.lexists(source):
dn = path.dirname(dest)
if not path.exists(dn):
makeDirectory(dn)
if path.lexists(dest):
if self.is_equal_system_backup(dest, source):
continue
shutil.copy2(source, dest)
fn_stat = os.lstat(source)
os.chown(dest, _uid(fn_stat.st_uid), _gid(fn_stat.st_gid))
if not notapply:
self.apply_files.add(dest)
return True
def clear_nm_connections(self, backup_path):
"""
Удалить доступные соединения для NetworkManager
:return:
"""
base_dir = pathJoin(backup_path, "root")
for fn in listDirectory(self.nm_connections, fullPath=True):
try:
if not path.exists(pathJoin(base_dir, fn)):
os.unlink(fn)
self.apply_files.add(fn)
except OSError as e:
raise BackupError(str(e))
def is_equal_files(self, text1, text2):
"""
Сравнить два файла отбросив комментарии и пробельные символы в начале и
в конце
:param text1:
:param text2:
:return:
"""
text1 = Template.removeComment(text1).strip()
text2 = Template.removeComment(text2).strip()
return text1 == text2
def is_equal_system_backup(self, system_fn, backup_fn):
"""
Проверить одинаковый ли файл в резервной копии и системе
:param system_fn:
:param backup_fn:
:return:
"""
_gid = lambda x: self.gid_map.get(x, x)
_uid = lambda x: self.uid_map.get(x, x)
if path.islink(system_fn) != path.islink(backup_fn):
return False
if path.islink(system_fn):
return os.readlink(system_fn) == os.readlink(backup_fn)
if path.isfile(system_fn) != path.isfile(backup_fn):
return False
data_system = readFile(system_fn)
data_backup = readFile(backup_fn)
if not self.is_equal_files(data_system, data_backup):
return False
stat_system = os.lstat(system_fn)
stat_backup = os.lstat(backup_fn)
if (stat.S_IMODE(stat_system.st_mode) !=
stat.S_IMODE(stat_backup.st_mode) or
stat_system.st_uid != _uid(stat_backup.st_uid) or
stat_system.st_gid != _gid(stat_backup.st_gid)):
return False
return True
def check_backup_for_network(self, backup_path, files):
"""
Проверить конфигурационные файлы настройки сети на соответствие текущим
:param backup_path:
:return:
"""
backup_nm = self.is_networkmanager_backup(backup_path)
system_nm = self.is_networkmanager_system()
# проверить совпадает ли сетевой менеджер
if backup_nm != system_nm:
if backup_nm and not any(
getInstalledAtom("net-misc/networkmanager")):
return True
return False
# если nm проверить совпадение system-connections
if backup_nm:
connection_files = set(path.basename(x) for x in chain(
glob.glob("%s/*" % self.nm_connections),
glob.glob("%s/*" % (pathJoin(backup_path, "root",
self.nm_connections)))
))
for fn in connection_files:
system_fn = pathJoin(self.nm_connections, fn)
backup_fn = pathJoin(backup_path, "root",
self.nm_connections, fn)
if not self.is_equal_system_backup(system_fn, backup_fn):
return False
# если openrc проверить conf.d/net и соответствие net.*
else:
system_fn = "/etc/conf.d/net"
backup_fn = pathJoin(backup_path, "root", system_fn)
if not self.is_equal_system_backup(system_fn, backup_fn):
return False
system_net_set = (set(path.basename(x)
for x in glob.glob('/etc/init.d/net.*')) -
{"net.lo"})
backup_net_set = set(path.basename(x) for x in files)
if system_net_set != backup_net_set:
return False
return True
def restore_network(self, backup_path):
"""
Восстановить сеть из backup
:param backup_path:
:return:
"""
files = ["/etc/init.d/%s" % x.strip()
for x in self.load_ini("backup", "init").split(',')
if x.startswith("net.") and x != "net.lo"]
if self.check_backup_for_network(backup_path, files):
self.endTask("skip")
return True
self.stop_net_services()
self.unlink_openrc_net_services(files)
self.clear_nm_connections(backup_path)
self.restore_files(backup_path, ["/etc/conf.d/hostname",
"/etc/resolv.conf",
"/etc/hosts"])
self._do_service("/etc/init.d/hostname", "restart")
if self.is_networkmanager_backup(backup_path):
self.unlink_openrc_net_services([])
self.restore_files(backup_path, [
"/etc/NetworkManager/system-connections/*",
"/etc/NetworkManager/dispatcher.d/*",
])
self._do_service("/etc/init.d/NetworkManager", "start")
else:
self.restore_files(backup_path, ["/etc/conf.d/net"])
self.restore_openrc_net_initd(files)
self._do_service("/etc/init.d/netmount", "start")
return True
def special_backup(self, backup_path):
"""
Выполнить специализирование резервное копирование модулей
:param backup_path:
:return:
"""
for backup_obj in self.iterate_modules():
backup_obj.backup(backup_path)
return True
def special_restore(self, backup_path):
"""
Выполнить специализирование восстановление из резервной копии
:param backup_path:
:return:
"""
for backup_obj in self.iterate_modules():
backup_obj.restore(backup_path)
return True
def iterate_modules(self):
"""
Перебрать все модули backup
:return:
"""
site_packages = [path.join(x, "calculate")
for x in sys.path
if (x.endswith('site-packages') and
x.startswith('/usr/lib'))]
ret_list = []
for module, modDir in chain(
*map(lambda x: map(lambda y: (path.basename(y), y),
listDirectory(x, True, True)),
site_packages)):
if path.exists(path.join(modDir, "backup_%s.py" % module)):
if not "calculate-%s" % module in ret_list:
ret_list.append("calculate-%s" % module)
cl_backup = ret_list
for pack in cl_backup:
if pack:
module_name = '%s.backup_%s' % (pack.replace("-", "."),
pack.rpartition("-")[2])
import importlib
try:
backup_module = importlib.import_module(module_name)
backup_obj = backup_module.Backup(self, self.clVars)
yield backup_obj
except ImportError:
sys.stderr.write(_("Unable to import %s") % module_name)
def display_changed_configs(self):
"""
Отобразить список восстановленных файлов
:return:
"""
t = Template(self.clVars, printWARNING=self.printWARNING,
printERROR=self.printERROR, printSUCCESS=self.printSUCCESS)
t.verboseOutput(sorted(list(self.apply_files | self.unlink_autorun)))
return True
def display_backup_configs(self, archfile):
"""
Отобразить список помещённых в резервную копию файлов
:return:
"""
with tarfile.open(archfile, 'r:bz2') as f:
self.printWARNING(_("Calculate Utilities have backuped files")
+ _(":"))
for fn in sorted("/%s" % x.path.partition('/')[2] for x in
f.getmembers() if (not x.isdir() and (
x.path.startswith("root") or
x.path.startswith("ldap")))):
self.printSUCCESS(" " * 5 + fn)
return True
def run_openrc(self, command):
p = process("/sbin/openrc", "default")
p.success()
return True
passwd_fn = '/etc/passwd'
group_fn = '/etc/group'
shadow_fn = '/etc/shadow'
def save_accounts(self, backup_path):
accounts_path = path.join(backup_path, "accounts")
for source_fn in (self.passwd_fn, self.group_fn, self.shadow_fn):
self.backup_file(source_fn, accounts_path, prefix="/etc")
return True
def restore_accounts(self, backup_path):
accounts_path = path.join(backup_path, "accounts")
backup_passwd_fn = pathJoin(accounts_path,
path.basename(self.passwd_fn))
backup_group_fn = pathJoin(accounts_path, path.basename(self.group_fn))
backup_shadow_fn = pathJoin(accounts_path,
path.basename(self.shadow_fn))
if any(not path.exists(x) for x in (backup_passwd_fn,
backup_group_fn,
backup_shadow_fn)):
return "skip"
# пользователи
passwd = Passwd(readFile(self.passwd_fn))
backup_passwd = Passwd(readFile(backup_passwd_fn))
added_users = [x.name for x in passwd.new_users(backup_passwd)]
keep_users = [x.name for x in backup_passwd.new_users(passwd)]
if self.clVars.GetBool('cl_backup_verbose_set') and added_users:
self.printSUCCESS(
_("Restored users:") + " " + ", ".join(added_users))
self.uid_map = backup_passwd.get_uid_map(passwd)
passwd.join(backup_passwd)
with open(makeCfgName(self.passwd_fn), 'w') as f:
passwd.write(f)
os.chown(self.passwd_fn, 0, 0)
os.chmod(self.passwd_fn,
FilePermission.OtherRead |
FilePermission.GroupRead |
FilePermission.UserRead |
FilePermission.UserWrite)
# группы
groups = Group(readFile(self.group_fn))
backup_groups = Group(readFile(backup_group_fn))
added_groups = [x.name for x in groups.new_groups(backup_groups)]
if self.clVars.GetBool('cl_backup_verbose_set') and added_groups:
self.printSUCCESS(_("Restored groups:") + " "
+ ", ".join(added_groups))
self.gid_map = backup_groups.get_gid_map(groups)
groups.join(backup_groups, keep_users=keep_users)
with open(makeCfgName(self.group_fn), 'w') as f:
groups.write(f)
os.chown(self.group_fn, 0, 0)
os.chmod(self.group_fn,
FilePermission.OtherRead |
FilePermission.GroupRead |
FilePermission.UserRead |
FilePermission.UserWrite)
# пароли
shadow = Shadow(readFile(self.shadow_fn))
backup_shadow = Shadow(readFile(backup_shadow_fn))
changed_shadow = [x.name
for x in shadow.changed_passwords(backup_shadow)]
if self.clVars.GetBool('cl_backup_verbose_set') and changed_shadow:
self.printSUCCESS(_("Restored user passwords:") + " "
+ ", ".join(changed_shadow))
shadow.join(backup_shadow)
with open(makeCfgName(self.shadow_fn), 'w') as f:
shadow.write(f)
os.chown(self.shadow_fn, 0, 0)
os.chmod(self.shadow_fn,
FilePermission.UserRead |
FilePermission.UserWrite)
return True

@ -1,322 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from __future__ import absolute_import
import os
import sys
from .sid_func import client_sid
from .function import get_sid, get_ip_mac_type
from .create_cert import (generateRSAKey, makePKey,
makeRequest, passphrase_callback)
import hashlib
from .client_class import HTTPSClientCertTransport
from .cert_verify import VerifyError
from calculate.core.datavars import DataVarsCore
from calculate.lib.utils.files import readFile
VERSION = 0.11
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def client_post_cert(client):
""" send a certificate server for check """
sid = get_sid(client.SID_FILE)
results = client.service.post_cert()
if results[0][0] == -4:
print(_("Certificate not found in the server database!"))
sys.exit(1)
client_sid(sid, client, cert_id=results[0][0])
if results[0][0] == -3:
print(_("Certificate not sent!"))
else:
print(_(" Your certifitate ID = %d") % (results[0][0]))
try:
if results[0][1] == -2:
print(_("Certificate expired"))
elif results[0][1] > 0:
print(_("The certificate expires after %d days") % (
results[0][1]))
except (IndexError, AttributeError):
pass
# Creation of secret key of the client
def new_key_req(key, cert_path, server_host_name, auto=False):
rsa = generateRSAKey()
rsa.save_key(key + '_pub', cipher=None, callback=passphrase_callback)
pkey = makePKey(rsa)
pkey.save_key(key, cipher=None, callback=passphrase_callback)
req = makeRequest(rsa, pkey, server_host_name, auto)
crtreq = req.as_pem()
req_file = os.path.join(cert_path, '%s.csr' % server_host_name)
crtfile = open(req_file, 'w')
crtfile.write(crtreq)
crtfile.close()
return req_file
def delete_old_cert(client):
os.unlink(client.CERT_FILE)
os.unlink(client.REQ_FILE)
os.unlink(client.PKEY_FILE)
os.unlink(client.PubKEY_FILE)
def client_post_request(cert_path, by_host):
if os.path.exists(cert_path + 'req_id'):
print(_("You already sent a certificate signature request."))
print(_("Request ID = %s") % readFile(cert_path + 'req_id'))
ans = raw_input(_("Send a new request? y/[n]: "))
if not ans.lower() in ['y', 'yes']:
return 0
port = raw_input(_("Enter the port number: "))
try:
port = int(port)
except ValueError:
print(_('The port number must be int'))
return 1
url = "https://%s:%d/?wsdl" % (by_host, port)
print(url + '\n' + _("connecting..."))
from suds.client import Client
# try:
client = Client(url, transport=HTTPSClientCertTransport(None, None,
cert_path))
# except (KeyboardInterrupt, urllib2.URLError), e:
# print '\n'+_("Closed. Connection error.")
# print _("Error code: %s") %e
# return 0
server_host_name = client.service.get_server_host_name()
key = cert_path + server_host_name + '.key'
csr_file = cert_path + server_host_name + '.csr'
if os.path.exists(key) and os.path.exists(csr_file):
print(_("the private key and request now exist"))
ask = raw_input(_("Create a new private key and request? y/[n]: "))
if ask.lower() in ['y', 'yes']:
new_key_req(key, cert_path, server_host_name)
else:
new_key_req(key, cert_path, server_host_name)
ip, mac, client_type = get_ip_mac_type()
data = readFile(csr_file)
res = client.service.post_client_request(request=data, ip=ip,
mac=mac, client_type=client_type)
if int(res) < 0:
print(_("This server is not enabled to sign certificates!"))
return 1
fc = open(cert_path + 'req_id', 'w')
fc.write(res)
fc.close()
print(_("Your request ID = %s") % res)
return 0
def client_get_cert(cert_path, args):
if not os.path.exists(cert_path + 'req_id'):
print(_("request not sent or file %s deleted") % (cert_path + 'req_id'))
return 1
fc = open(cert_path + 'req_id', 'r')
req_id = fc.read()
fc.close()
print('\n' + _("the URL looks like"), "https://%s:[port]/?wsdl" \
% args.from_host)
port = raw_input(_("Enter the port number: "))
try:
port = int(port)
except ValueError:
print(_('The port number must be int'))
return 1
url = "https://%s:%d/?wsdl" % (args.from_host, port)
print(url + '\n' + _("connecting..."))
from suds.client import Client
try:
client = Client(url, transport=HTTPSClientCertTransport(None, None,
cert_path))
except KeyboardInterrupt:
print('\n' + _("Closed. Connection error."))
return 1
server_host_name = client.service.get_server_host_name()
if not os.path.exists(cert_path + server_host_name + '.csr'):
print(_('Request %s not found') % (
cert_path + server_host_name + '.csr'))
return 1
request = readFile(cert_path + server_host_name + '.csr')
md5 = hashlib.md5()
md5.update(request)
md5sum = md5.hexdigest()
result = client.service.get_client_cert(req_id, md5sum)
cert = result[0][0]
ca_root = result[0][1]
if cert == '1':
print(_('The signature request was rejected!'))
return 1
elif cert == '2':
print(_("The signature request has not been examined yet."))
print(_("Your request ID = %s") % req_id)
return 1
elif cert == '3':
print(_("The signature request does not match earlier data."))
return 1
elif cert == '4':
print(_("The request was sent from another IP."))
return 1
fc = open(cert_path + server_host_name + '.crt', 'w')
fc.write(cert)
fc.close()
os.unlink(cert_path + 'req_id')
print('OK. Certificate saved. Your certificate ID = %s' % req_id)
if ca_root:
cl_vars = DataVarsCore()
cl_vars.importCore()
cl_vars.flIniFile()
system_ca_db = cl_vars.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if ca_root in readFile(system_ca_db):
return 0
cl_client_cert_dir = cl_vars.Get('cl_client_cert_dir')
home_path = cl_vars.Get('ur_home_path')
cl_client_cert_dir = cl_client_cert_dir.replace("~", home_path)
root_cert_md5 = cl_client_cert_dir + "/ca/cert_list"
md5 = hashlib.md5()
md5.update(ca_root)
md5sum = md5.hexdigest()
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5, "w")
fc.close()
filename = None
with open(root_cert_md5) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split(' ', 1)
if words[0] == md5sum:
filename = words[1]
import OpenSSL
if not filename:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, ca_root)
issuer = certobj.get_issuer().get_components()
for item in issuer:
if item[0] == 'CN':
filename = item[1]
fc = open(root_cert_md5, "a")
fc.write('%s %s\n' % (md5sum, filename))
fc.close()
if not filename:
print(_('Field "CN" not found in the certificate!'))
return 1
fd = open(cl_client_cert_dir + '/ca/' + filename, 'w')
fd.write(ca_root)
fd.close()
user_root_cert = cl_vars.Get('cl_user_root_cert')
user_root_cert = user_root_cert.replace("~", home_path)
fa = open(user_root_cert, 'a')
fa.write(ca_root)
fa.close()
print(_("Certificate added"))
else:
print(_("file containing the CA certificate now exists"))
return 0
def client_post_auth(client):
""" authorization client or post request """
sid = get_sid(client.SID_FILE)
try:
if os.path.exists(client.CERT_FILE):
pass # client_post_cert(client)
else:
# client_post_request(client)
print(_('You do not have a certificate. Use option '
'--gen-cert-by HOST to generate a new certificate '
'or --get-cert-from HOST to get the certificate '
'from the server.'))
sys.exit()
print(client.service.versions(sid, VERSION))
except VerifyError as e:
print(e.value)
sys.exit()
# show rights on requested certificated
def cert_right_inf(client, sid, cert_id):
s = client.service.view_cert_right(cert_id)
if s[0][0] == "-1":
print(_("Certificate not found on the server!"))
return -1
if s[0][0] == "-2":
print(_("Failed to create the certificate ID!"))
return -2
if s[0][0] == "Permission denied":
print(_("%s: Permission denied") % s[0][1])
return -3
print(_("The certificate with ID = %d can execute:") % cert_id)
for meth in s[0]:
print(" - %s" % meth)
# Viewing rights of any certificate on server by its id
def client_view_cert_right(client):
cert_id = raw_input(_("Certificate ID: "))
try:
cert_id = int(cert_id)
except ValueError:
print(_("Invalid certificate ID"))
return 1
try:
sid = get_sid(client.SID_FILE)
if cert_id > 0:
cert_right_inf(client, sid, cert_id)
else:
print(_("Please enter a valid certificate ID!"))
except Exception as e:
if e[0][0] == 403:
print(_('Permission denied'))
else:
print(e)
# print _("Failed to get data")
return 1
return 0

@ -1,320 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
from sid_func import client_sid
from function import get_sid, get_ip_mac_type
from create_cert import (generateRSAKey, makePKey,
makeRequest, passphrase_callback)
import hashlib
from client_class import HTTPSClientCertTransport
from cert_verify import VerifyError
from calculate.core.datavars import DataVarsCore
from calculate.lib.utils.files import readFile
VERSION = 0.11
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def client_post_cert(client):
""" send a certificate server for check """
sid = get_sid(client.SID_FILE)
results = client.service.post_cert()
if results[0][0] == -4:
print _("Certificate not found in the server database!")
sys.exit(1)
client_sid(sid, client, cert_id=results[0][0])
if results[0][0] == -3:
print _("Certificate not sent!")
else:
print _(" Your certifitate ID = %d") % (results[0][0])
try:
if results[0][1] == -2:
print _("Certificate expired")
elif results[0][1] > 0:
print _("The certificate expires after %d days") % (
results[0][1])
except (IndexError, AttributeError):
pass
# Creation of secret key of the client
def new_key_req(key, cert_path, server_host_name, auto=False):
rsa = generateRSAKey()
rsa.save_key(key + '_pub', cipher=None, callback=passphrase_callback)
pkey = makePKey(rsa)
pkey.save_key(key, cipher=None, callback=passphrase_callback)
req = makeRequest(rsa, pkey, server_host_name, auto)
crtreq = req.as_pem()
req_file = os.path.join(cert_path, '%s.csr' % server_host_name)
crtfile = open(req_file, 'w')
crtfile.write(crtreq)
crtfile.close()
return req_file
def delete_old_cert(client):
os.unlink(client.CERT_FILE)
os.unlink(client.REQ_FILE)
os.unlink(client.PKEY_FILE)
os.unlink(client.PubKEY_FILE)
def client_post_request(cert_path, by_host):
if os.path.exists(cert_path + 'req_id'):
print _("You already sent a certificate signature request.")
print _("Request ID = %s") % readFile(cert_path + 'req_id')
ans = raw_input(_("Send a new request? y/[n]: "))
if not ans.lower() in ['y', 'yes']:
return 0
port = raw_input(_("Enter the port number: "))
try:
port = int(port)
except ValueError:
print _('The port number must be int')
return 1
url = "https://%s:%d/?wsdl" % (by_host, port)
print url + '\n' + _("connecting...")
from suds.client import Client
# try:
client = Client(url, transport=HTTPSClientCertTransport(None, None,
cert_path))
# except (KeyboardInterrupt, urllib2.URLError), e:
# print '\n'+_("Closed. Connection error.")
# print _("Error code: %s") %e
# return 0
server_host_name = client.service.get_server_host_name()
key = cert_path + server_host_name + '.key'
csr_file = cert_path + server_host_name + '.csr'
if os.path.exists(key) and os.path.exists(csr_file):
print _("the private key and request now exist")
ask = raw_input(_("Create a new private key and request? y/[n]: "))
if ask.lower() in ['y', 'yes']:
new_key_req(key, cert_path, server_host_name)
else:
new_key_req(key, cert_path, server_host_name)
ip, mac, client_type = get_ip_mac_type()
data = readFile(csr_file)
res = client.service.post_client_request(request=data, ip=ip,
mac=mac, client_type=client_type)
if int(res) < 0:
print _("This server is not enabled to sign certificates!")
return 1
fc = open(cert_path + 'req_id', 'w')
fc.write(res)
fc.close()
print _("Your request ID = %s") % res
return 0
def client_get_cert(cert_path, args):
if not os.path.exists(cert_path + 'req_id'):
print _("request not sent or file %s deleted") % (cert_path + 'req_id')
return 1
fc = open(cert_path + 'req_id', 'r')
req_id = fc.read()
fc.close()
print '\n' + _("the URL looks like"), "https://%s:[port]/?wsdl" \
% args.from_host
port = raw_input(_("Enter the port number: "))
try:
port = int(port)
except ValueError:
print _('The port number must be int')
return 1
url = "https://%s:%d/?wsdl" % (args.from_host, port)
print url + '\n' + _("connecting...")
from suds.client import Client
try:
client = Client(url, transport=HTTPSClientCertTransport(None, None,
cert_path))
except KeyboardInterrupt:
print '\n' + _("Closed. Connection error.")
return 1
server_host_name = client.service.get_server_host_name()
if not os.path.exists(cert_path + server_host_name + '.csr'):
print _('Request %s not found') % (
cert_path + server_host_name + '.csr')
return 1
request = readFile(cert_path + server_host_name + '.csr')
md5 = hashlib.md5()
md5.update(request)
md5sum = md5.hexdigest()
result = client.service.get_client_cert(req_id, md5sum)
cert = result[0][0]
ca_root = result[0][1]
if cert == '1':
print _('The signature request was rejected!')
return 1
elif cert == '2':
print _("The signature request has not been examined yet.")
print _("Your request ID = %s") % req_id
return 1
elif cert == '3':
print _("The signature request does not match earlier data.")
return 1
elif cert == '4':
print _("The request was sent from another IP.")
return 1
fc = open(cert_path + server_host_name + '.crt', 'w')
fc.write(cert)
fc.close()
os.unlink(cert_path + 'req_id')
print 'OK. Certificate saved. Your certificate ID = %s' % req_id
if ca_root:
cl_vars = DataVarsCore()
cl_vars.importCore()
cl_vars.flIniFile()
system_ca_db = cl_vars.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if ca_root in readFile(system_ca_db):
return 0
cl_client_cert_dir = cl_vars.Get('cl_client_cert_dir')
home_path = cl_vars.Get('ur_home_path')
cl_client_cert_dir = cl_client_cert_dir.replace("~", home_path)
root_cert_md5 = cl_client_cert_dir + "/ca/cert_list"
md5 = hashlib.md5()
md5.update(ca_root)
md5sum = md5.hexdigest()
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5, "w")
fc.close()
filename = None
with open(root_cert_md5) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split(' ', 1)
if words[0] == md5sum:
filename = words[1]
import OpenSSL
if not filename:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, ca_root)
issuer = certobj.get_issuer().get_components()
for item in issuer:
if item[0] == 'CN':
filename = item[1]
fc = open(root_cert_md5, "a")
fc.write('%s %s\n' % (md5sum, filename))
fc.close()
if not filename:
print _('Field "CN" not found in the certificate!')
return 1
fd = open(cl_client_cert_dir + '/ca/' + filename, 'w')
fd.write(ca_root)
fd.close()
user_root_cert = cl_vars.Get('cl_user_root_cert')
user_root_cert = user_root_cert.replace("~", home_path)
fa = open(user_root_cert, 'a')
fa.write(ca_root)
fa.close()
print _("Certificate added")
else:
print _("file containing the CA certificate now exists")
return 0
def client_post_auth(client):
""" authorization client or post request """
sid = get_sid(client.SID_FILE)
try:
if os.path.exists(client.CERT_FILE):
pass # client_post_cert(client)
else:
# client_post_request(client)
print _('You do not have a certificate. Use option '
'--gen-cert-by HOST to generate a new certificate '
'or --get-cert-from HOST to get the certificate '
'from the server.')
sys.exit()
print client.service.versions(sid, VERSION)
except VerifyError, e:
print e.value
sys.exit()
# show rights on requested certificated
def cert_right_inf(client, sid, cert_id):
s = client.service.view_cert_right(cert_id)
if s[0][0] == "-1":
print _("Certificate not found on the server!")
return -1
if s[0][0] == "-2":
print _("Failed to create the certificate ID!")
return -2
if s[0][0] == "Permission denied":
print _("%s: Permission denied") % s[0][1]
return -3
print _("The certificate with ID = %d can execute:") % cert_id
for meth in s[0]:
print " - %s" % meth
# Viewing rights of any certificate on server by its id
def client_view_cert_right(client):
cert_id = raw_input(_("Certificate ID: "))
try:
cert_id = int(cert_id)
except ValueError:
print _("Invalid certificate ID")
return 1
try:
sid = get_sid(client.SID_FILE)
if cert_id > 0:
cert_right_inf(client, sid, cert_id)
else:
print _("Please enter a valid certificate ID!")
except Exception, e:
if e[0][0] == 403:
print _('Permission denied')
else:
print e
# print _("Failed to get data")
return 1
return 0

@ -1,312 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from __future__ import absolute_import
import sys
import os
import re
from calculate.core.datavars import DataVarsCore
from calculate.lib.utils.files import readFile
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
class VerifyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
# check recall of server certificate
def verify(server_cert, crl_path, flag):
import OpenSSL
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
server_cert)
serverSerial = certobj.get_serial_number()
Issuer = certobj.get_issuer().get_components()
CN, L = None, None
for i in Issuer:
if i[0] == 'CN':
CN = i[1]
elif i[0] == 'L':
L = i[1]
if CN and len(CN) > 2:
crl_file = crl_path + CN
elif L:
try:
host = L.split(':')[0]
except Exception:
if not flag:
print(_('The CN and L fields in the CA certificate are '
'incorrect!'))
return 0
crl_file = crl_path + host
else:
if not flag:
print(_('The CN and L fields in the CA certificate are incorrect!'))
return 0
if not os.path.exists(crl_file):
if not flag:
print(_("This certificate cannot be verified in the CRL."))
return 0
with open(crl_file, 'r') as _crl_file:
crl = "".join(_crl_file.readlines())
if crl == '':
return 0
crl_object = OpenSSL.crypto.load_crl(OpenSSL.crypto.FILETYPE_PEM, crl)
revoked_objects = crl_object.get_revoked()
for rvk in revoked_objects:
if serverSerial == int(rvk.get_serial(), 16):
print(_("This certificate has been revoked!"))
print (_("Serial") + ': %s\n' % rvk.get_serial() +
_("Revoke date") + _(': %s') % rvk.get_rev_date())
raise VerifyError('CRL Exception')
return 0
def get_CRL(path_to_cert):
""" get new CRL (Certificate Revocation List) from all CA """
# local CRL
CRL_path = path_to_cert + 'ca/crl/'
if not os.path.exists(CRL_path):
if not os.path.exists(path_to_cert + '/ca'):
if not os.path.exists(path_to_cert):
try:
os.makedirs(path_to_cert)
except OSError:
print(_("Error creating directory %s") % path_to_cert)
sys.exit()
try:
os.makedirs(path_to_cert + '/ca')
except OSError:
print(_("Error creating directory %s") % (path_to_cert + '/ca'))
sys.exit()
os.makedirs(CRL_path)
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
# user and system ca and root certificates
user_root_cert = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_root_cert = user_root_cert.replace("~", homePath)
glob_root_cert = clVars.Get('cl_glob_root_cert')
if os.path.exists(user_root_cert):
user_ca_certs = readFile(user_root_cert)
else:
user_ca_certs = ''
if os.path.exists(glob_root_cert):
glob_ca_certs = readFile(glob_root_cert)
else:
glob_ca_certs = ''
# get certificates list fron text
p = re.compile('[-]+[\w ]+[-]+\n+[\w\n\+\\=/]+[-]+[\w ]+[-]+\n?')
user_ca_certs_list = p.findall(user_ca_certs)
glob_ca_certs_list = p.findall(glob_ca_certs)
# association in one list
all_ca_certs_list = user_ca_certs_list + glob_ca_certs_list
import OpenSSL
for ca in all_ca_certs_list:
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM, ca)
# get url from certificates
url = None
CN = None
Subject = certobj.get_subject().get_components()
subj = None
for subj in Subject:
if subj[0] == 'L':
url = "https://" + subj[1] + "/?wsdl"
if subj[0] == 'CN':
CN = subj[1]
if subj and url:
from calculate.core.client.client_class import Client_suds
from .client_class import HTTPSClientCertTransport
# connect to ca server (url get from certificates)
try:
client = Client_suds(url, transport=HTTPSClientCertTransport(
None, None, path_to_cert))
client.set_parameters(path_to_cert, None, None)
new_crl = client.service.get_crl()
if new_crl:
if CN and len(CN) > 2:
CRL_file = CRL_path + CN
else:
host = subj[1].split(':')[0]
CRL_file = CRL_path + host
if new_crl == ' ':
open(CRL_file, 'w').close()
# if os.path.exists(CRL_file):
# os.unlink(CRL_file)
continue
if os.path.exists(CRL_file):
if readFile(CRL_file) == new_crl:
continue
with open(CRL_file, 'w') as fd:
fd.write(new_crl)
print(_("CRL added"))
except VerifyError as e:
print(e.value)
# rm_ca_from_trusted(ca)
sys.exit()
except Exception:
pass
find_ca_in_crl(CRL_path, all_ca_certs_list)
def find_ca_in_crl(CRL_path, all_ca_certs_list):
import OpenSSL
for ca in all_ca_certs_list:
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
ca)
Issuer = certobj.get_issuer().get_components()
for item in Issuer:
if item[0] == 'CN':
CN = item[1]
break
else:
continue
server_serial = certobj.get_serial_number()
CRL = CRL_path + CN
if not os.path.exists(CRL):
continue
with open(CRL, 'r') as _crl_file:
crl = "".join(_crl_file.readlines())
try:
crl_object = OpenSSL.crypto.load_crl(OpenSSL.crypto.FILETYPE_PEM,
crl)
except OpenSSL.SSL.Error:
continue
revoked_objects = crl_object.get_revoked()
for rvk in revoked_objects:
if server_serial == int(rvk.get_serial(), 16):
rm_ca_from_trusted(ca)
def rm_ca_from_trusted(ca_cert):
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
user_ca_dir = clVars.Get('cl_client_cert_dir')
homePath = clVars.Get('ur_home_path')
user_ca_dir = user_ca_dir.replace("~", homePath)
user_ca_dir = os.path.join(user_ca_dir, 'ca')
user_ca_list = os.path.join(user_ca_dir, 'cert_list')
user_ca_db = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_ca_db = user_ca_db.replace("~", homePath)
system_ca_dir = clVars.Get('cl_core_cert_path')
system_ca_db = clVars.Get('cl_glob_root_cert')
import hashlib
md5 = hashlib.md5()
md5.update(ca_cert)
md5sum = md5.hexdigest()
# search ca certificate in user ca list
newfile = ''
with open(user_ca_list) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
newfile = ''
# and each word in line
words = line.split()
if words[0] == md5sum:
filename = os.path.join(user_ca_dir, words[1])
if ca_cert == readFile(filename):
os.unlink(filename)
else:
newfile += (line + '\n')
else:
newfile += (line + '\n')
fd.close()
fn = open(user_ca_list, 'w')
fn.write(newfile)
fn.close()
p = re.compile('[-]+[\w ]+[-]+\n+[\w\n\+\\=/]+[-]+[\w ]+[-]+\n?')
# open, write and split user ca certificates
user_ca_certs = readFile(user_ca_db)
user_ca_certs_list = p.findall(user_ca_certs)
if ca_cert in user_ca_certs_list:
new_user_ca_certs = []
for cert in user_ca_certs_list:
if ca_cert != cert:
new_user_ca_certs.append(cert)
else:
print(_("CA certificate deleted from the user's trusted "
"certificates list"))
with open(user_ca_db, 'w') as fd:
for cert in new_user_ca_certs:
fd.write(cert)
if not os.path.exists(system_ca_db):
open(system_ca_db, 'w').close()
system_ca_certs = readFile(system_ca_db)
system_ca_certs_list = p.findall(system_ca_certs)
if ca_cert in system_ca_certs_list:
new_system_ca_certs = []
for cert in system_ca_certs_list:
if ca_cert != cert:
new_system_ca_certs.append(cert)
else:
print(_('CA certificate deleted from the system trusted '
'certificates list'))
fd = open(system_ca_db, 'w')
for cert in new_system_ca_certs:
fd.write(cert)
fd.close()
return 0

@ -1,310 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import os
import re
from calculate.core.datavars import DataVarsCore
from calculate.lib.utils.files import readFile
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
class VerifyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
# check recall of server certificate
def verify(server_cert, crl_path, flag):
import OpenSSL
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
server_cert)
serverSerial = certobj.get_serial_number()
Issuer = certobj.get_issuer().get_components()
CN, L = None, None
for i in Issuer:
if i[0] == 'CN':
CN = i[1]
elif i[0] == 'L':
L = i[1]
if CN and len(CN) > 2:
crl_file = crl_path + CN
elif L:
try:
host = L.split(':')[0]
except Exception:
if not flag:
print _('The CN and L fields in the CA certificate are '
'incorrect!')
return 0
crl_file = crl_path + host
else:
if not flag:
print _('The CN and L fields in the CA certificate are incorrect!')
return 0
if not os.path.exists(crl_file):
if not flag:
print _("This certificate cannot be verified in the CRL.")
return 0
with open(crl_file, 'r') as _crl_file:
crl = "".join(_crl_file.readlines())
if crl == '':
return 0
crl_object = OpenSSL.crypto.load_crl(OpenSSL.crypto.FILETYPE_PEM, crl)
revoked_objects = crl_object.get_revoked()
for rvk in revoked_objects:
if serverSerial == int(rvk.get_serial(), 16):
print _("This certificate has been revoked!")
print (_("Serial") + ': %s\n' % rvk.get_serial() +
_("Revoke date") + _(': %s') % rvk.get_rev_date())
raise VerifyError('CRL Exception')
return 0
def get_CRL(path_to_cert):
""" get new CRL (Certificate Revocation List) from all CA """
# local CRL
CRL_path = path_to_cert + 'ca/crl/'
if not os.path.exists(CRL_path):
if not os.path.exists(path_to_cert + '/ca'):
if not os.path.exists(path_to_cert):
try:
os.makedirs(path_to_cert)
except OSError:
print _("Error creating directory %s") % path_to_cert
sys.exit()
try:
os.makedirs(path_to_cert + '/ca')
except OSError:
print _("Error creating directory %s") % (path_to_cert + '/ca')
sys.exit()
os.makedirs(CRL_path)
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
# user and system ca and root certificates
user_root_cert = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_root_cert = user_root_cert.replace("~", homePath)
glob_root_cert = clVars.Get('cl_glob_root_cert')
if os.path.exists(user_root_cert):
user_ca_certs = readFile(user_root_cert)
else:
user_ca_certs = ''
if os.path.exists(glob_root_cert):
glob_ca_certs = readFile(glob_root_cert)
else:
glob_ca_certs = ''
# get certificates list fron text
p = re.compile('[-]+[\w ]+[-]+\n+[\w\n\+\\=/]+[-]+[\w ]+[-]+\n?')
user_ca_certs_list = p.findall(user_ca_certs)
glob_ca_certs_list = p.findall(glob_ca_certs)
# association in one list
all_ca_certs_list = user_ca_certs_list + glob_ca_certs_list
import OpenSSL
for ca in all_ca_certs_list:
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM, ca)
# get url from certificates
url = None
CN = None
Subject = certobj.get_subject().get_components()
subj = None
for subj in Subject:
if subj[0] == 'L':
url = "https://" + subj[1] + "/?wsdl"
if subj[0] == 'CN':
CN = subj[1]
if subj and url:
from calculate.core.client.client_class import Client_suds
from client_class import HTTPSClientCertTransport
# connect to ca server (url get from certificates)
try:
client = Client_suds(url, transport=HTTPSClientCertTransport(
None, None, path_to_cert))
client.set_parameters(path_to_cert, None, None)
new_crl = client.service.get_crl()
if new_crl:
if CN and len(CN) > 2:
CRL_file = CRL_path + CN
else:
host = subj[1].split(':')[0]
CRL_file = CRL_path + host
if new_crl == ' ':
open(CRL_file, 'w').close()
# if os.path.exists(CRL_file):
# os.unlink(CRL_file)
continue
if os.path.exists(CRL_file):
if readFile(CRL_file) == new_crl:
continue
with open(CRL_file, 'w') as fd:
fd.write(new_crl)
print _("CRL added")
except VerifyError as e:
print e.value
# rm_ca_from_trusted(ca)
sys.exit()
except Exception:
pass
find_ca_in_crl(CRL_path, all_ca_certs_list)
def find_ca_in_crl(CRL_path, all_ca_certs_list):
import OpenSSL
for ca in all_ca_certs_list:
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
ca)
Issuer = certobj.get_issuer().get_components()
for item in Issuer:
if item[0] == 'CN':
CN = item[1]
break
else:
continue
server_serial = certobj.get_serial_number()
CRL = CRL_path + CN
if not os.path.exists(CRL):
continue
with open(CRL, 'r') as _crl_file:
crl = "".join(_crl_file.readlines())
try:
crl_object = OpenSSL.crypto.load_crl(OpenSSL.crypto.FILETYPE_PEM,
crl)
except OpenSSL.SSL.Error:
continue
revoked_objects = crl_object.get_revoked()
for rvk in revoked_objects:
if server_serial == int(rvk.get_serial(), 16):
rm_ca_from_trusted(ca)
def rm_ca_from_trusted(ca_cert):
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
user_ca_dir = clVars.Get('cl_client_cert_dir')
homePath = clVars.Get('ur_home_path')
user_ca_dir = user_ca_dir.replace("~", homePath)
user_ca_dir = os.path.join(user_ca_dir, 'ca')
user_ca_list = os.path.join(user_ca_dir, 'cert_list')
user_ca_db = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_ca_db = user_ca_db.replace("~", homePath)
system_ca_dir = clVars.Get('cl_core_cert_path')
system_ca_db = clVars.Get('cl_glob_root_cert')
import hashlib
md5 = hashlib.md5()
md5.update(ca_cert)
md5sum = md5.hexdigest()
# search ca certificate in user ca list
newfile = ''
with open(user_ca_list) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
newfile = ''
# and each word in line
words = line.split()
if words[0] == md5sum:
filename = os.path.join(user_ca_dir, words[1])
if ca_cert == readFile(filename):
os.unlink(filename)
else:
newfile += (line + '\n')
else:
newfile += (line + '\n')
fd.close()
fn = open(user_ca_list, 'w')
fn.write(newfile)
fn.close()
p = re.compile('[-]+[\w ]+[-]+\n+[\w\n\+\\=/]+[-]+[\w ]+[-]+\n?')
# open, write and split user ca certificates
user_ca_certs = readFile(user_ca_db)
user_ca_certs_list = p.findall(user_ca_certs)
if ca_cert in user_ca_certs_list:
new_user_ca_certs = []
for cert in user_ca_certs_list:
if ca_cert != cert:
new_user_ca_certs.append(cert)
else:
print _("CA certificate deleted from the user's trusted "
"certificates list")
with open(user_ca_db, 'w') as fd:
for cert in new_user_ca_certs:
fd.write(cert)
if not os.path.exists(system_ca_db):
open(system_ca_db, 'w').close()
system_ca_certs = readFile(system_ca_db)
system_ca_certs_list = p.findall(system_ca_certs)
if ca_cert in system_ca_certs_list:
new_system_ca_certs = []
for cert in system_ca_certs_list:
if ca_cert != cert:
new_system_ca_certs.append(cert)
else:
print _('CA certificate deleted from the system trusted '
'certificates list')
fd = open(system_ca_db, 'w')
for cert in new_system_ca_certs:
fd.write(cert)
fd.close()
return 0

@ -1,485 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from __future__ import absolute_import
import urllib2 as u2
import os
import sys
import calculate.contrib
from suds.transport.http import HttpTransport
import httplib #http.client in python3
from httplib import HTTPConnection
import socket
import ssl
import hashlib
from calculate.core.datavars import DataVarsCore
from calculate.lib.datavars import DataVars
from calculate.lib.utils.files import readFile
from suds.client import Client
from .cert_verify import verify, get_CRL
if hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
else:
ssl_version = None
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
flag = 0
class Client_suds(Client):
def set_parameters(self, path_to_cert, CERT_FILE, PKEY_FILE):
self.path_to_cert = path_to_cert
if not CERT_FILE:
CERT_FILE = ''
self.CERT_FILE = CERT_FILE
self.REQ_FILE = path_to_cert + 'client.csr'
self.PKEY_FILE = PKEY_FILE
self.SID_FILE = path_to_cert + 'sid.int'
self.CRL_PATH = path_to_cert + 'ca/crl/'
if not os.path.exists(self.CRL_PATH):
os.makedirs(self.CRL_PATH)
class clientHTTPSConnection(httplib.HTTPSConnection):
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, cert_path=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
self.cert_path = cert_path
self.CRL_PATH = cert_path + 'ca/crl/'
# get filename store cert server
def cert_list(self, host, ca_certs, server_cert):
if host == '127.0.0.1':
host = 'localhost'
if not os.path.exists(self.trusted_path):
try:
os.makedirs(self.trusted_path)
except OSError:
pass
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
filename = None
try:
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
filename = words[1]
if not filename:
return None
except (IndexError, IOError):
print(_("Certificate not found on the client's side"))
return None
try:
with open(self.trusted_path + filename, 'r') as fd:
store_cert = fd.read()
if store_cert == server_cert:
return filename
except IOError:
print(_("Failed to open the file"), self.trusted_path, filename)
return None
def add_all_ca_cert(self, list_ca_certs):
# so root cert be first, ca after
clVarsCore = DataVarsCore()
clVarsCore.importCore()
clVarsCore.flIniFile()
list_ca_certs.reverse()
import OpenSSL
for cert in list_ca_certs:
system_ca_db = clVarsCore.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if cert in readFile(system_ca_db):
continue
clVars = DataVars()
clVars.flIniFile()
homePath = clVars.Get('ur_home_path')
user_root_cert = clVarsCore.Get('cl_user_root_cert')
user_root_cert = user_root_cert.replace("~", homePath)
if os.path.exists(user_root_cert):
if cert in readFile(user_root_cert):
continue
cl_client_cert_dir = clVarsCore.Get('cl_client_cert_dir')
cl_client_cert_dir = cl_client_cert_dir.replace("~", homePath)
root_cert_md5 = cl_client_cert_dir + "/ca/cert_list"
md5 = hashlib.md5()
md5.update(cert)
md5sum = md5.hexdigest()
print("\n=================================================")
print("md5sum = ", md5sum)
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5, "w")
fc.close()
filename = None
with open(root_cert_md5) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split(' ', 1)
if words[0] == md5sum:
filename = words[1]
if not filename:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
Issuer = certobj.get_issuer().get_components()
for item in Issuer:
if item[0] == 'CN':
filename = item[1]
fc = open(root_cert_md5, "a")
fc.write('%s %s\n' % (md5sum, filename))
fc.close()
if not filename:
print(_('Field "CN" not found in the certificate!'))
return 1
fd = open(cl_client_cert_dir + '/ca/' + filename, 'w')
fd.write(cert)
fd.close()
fa = open(user_root_cert, 'a')
fa.write(cert)
fa.close()
print(_("filename = "), filename)
print(_("Certificate added"))
else:
print(_("file containing the CA certificate now exists"))
get_CRL(cl_client_cert_dir + '/')
def add_ca_cert(self, cert, list_ca_certs):
url = 'https://%s:%s/?wsdl' % (self.host, self.port)
client = Client_suds(url, transport=HTTPSClientCertTransport(
None, None, self.cert_path))
cert = client.service.get_ca()
if cert == '1':
print(_("Invalid server certificate!"))
sys.exit()
if cert == '2':
print(_("CA certificate not found on the server"))
sys.exit()
import OpenSSL
try:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
except (OpenSSL.SSL.Error, IOError):
print(_("Error. Certificate not added to the trusted list."))
sys.exit()
print('\n' + _("Fingerprint = %s") % certobj.digest('SHA1'))
print(_("Serial number = "), certobj.get_serial_number())
Issuer = certobj.get_issuer().get_components()
print('\n' + _("Issuer"))
for i in Issuer:
print("%s : %s" % (i[0], i[1]))
Subject = certobj.get_subject().get_components()
print('\n' + _("Subject"))
for subj in Subject:
print("%s : %s" % (subj[0], subj[1]))
ans = raw_input(_("Add the CA certificate to trusted? y/[n]:"))
if ans.lower() in ['y', 'yes']:
list_ca_certs.append(cert)
self.add_all_ca_cert(list_ca_certs)
else:
print(_("Certificate not added to trusted"))
sys.exit()
# add certificate server in trusted
def add_server_cert(self, cert):
import OpenSSL
print(_("Untrusted server certificate!"))
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
cert)
print('\n' + _("Fingerprint = %s") % certobj.digest('SHA1'))
print(_("Serial number = "), certobj.get_serial_number())
Issuer = certobj.get_issuer().get_components()
print('\n' + _("Issuer"))
for i in Issuer:
print("%s : %s" % (i[0], i[1]))
Subject = certobj.get_subject().get_components()
print('\n' + _("Subject"))
for item in Subject:
print("%s : %s" % (item[0], item[1]))
print('\n' + _('Add this server certificate to trusted (s) or'))
print(_('Try to add the CA and root certificates to trusted (c) or'))
choice = raw_input(_("Quit (q)? s/c/[q]: "))
if choice.lower() in ['s', 'c']:
# self.sock = ssl.wrap_socket(sock)
ca_certs = self.trusted_path + "cert.list"
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
if self.host == '127.0.0.1':
host = 'localhost'
else:
host = self.host
filename = host
fc = open(self.trusted_path + filename, "w")
fc.write(cert)
fc.close()
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
return 0
# Open file with compliance server certificates and server hostname
fcl = open(ca_certs, "a")
fcl.write(host + ' ' + filename + '\n')
fcl.close()
if choice.lower() == 'c':
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
cl_client_cert_dir = clVars.Get('cl_client_cert_dir')
homePath = clVars.Get('ur_home_path')
cl_client_cert_dir = cl_client_cert_dir.replace("~", homePath)
root_cert_dir = cl_client_cert_dir + "/ca"
if not os.path.exists(root_cert_dir):
try:
os.makedirs(root_cert_dir)
except OSError:
print(_("Error creating directory %s") % root_cert_dir)
sys.exit()
print('\n' + _("Add the CA and root certificates"))
self.list_ca_certs = []
self.add_ca_cert(cert, self.list_ca_certs)
sys.exit()
else:
sys.exit()
def connect_trusted_root(self, sock, root_cert, crl_certs):
self.ca_path = self.cert_path + "ca/"
server_cert = ssl.get_server_certificate(addr=(self.host, self.port))
global flag
if self.cert_file:
f = verify(server_cert, crl_certs, flag)
if not f:
flag = 1
elif f == 1:
sys.exit()
else:
import time
time.sleep(1)
try:
if ssl_version is None:
print(_("SSL library is not support TLSv1_2"))
self.sock.close()
return 2
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ca_certs=root_cert,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_REQUIRED)
dercert_after_connect = self.sock.getpeercert(True)
cert_after_connect = \
ssl.DER_cert_to_PEM_cert(dercert_after_connect)
if not server_cert == cert_after_connect:
print ('\n' +
_("WARNING! %s trying to replace the certificate!")
% self.host + '\n')
self.sock.close()
return 2
return 0
except Exception:
return 1
def connect_trusted_server(self, sock, crl_certs):
self.trusted_path = self.cert_path + "trusted/"
ca_cert_list = self.trusted_path + "cert.list"
server_cert = ssl.get_server_certificate(addr=(self.host, self.port))
global flag
if self.cert_file:
f = verify(server_cert, crl_certs, flag)
if not f:
flag = 1
elif f == 1:
sys.exit()
HTTPSClientCertTransport.filename = self.cert_list(
self.host, ca_cert_list, server_cert)
if HTTPSClientCertTransport.filename:
try:
if ssl_version is None:
print(_("SSL library is not support TLSv1_2"))
HTTPSClientCertTransport.filename = None
self.sock.close()
return 1
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_NONE)
dercert_after_connect = self.sock.getpeercert(True)
ssl.DER_cert_to_PEM_cert(dercert_after_connect)
return 0
except Exception as e:
print(e)
HTTPSClientCertTransport.filename = None
return 1
else:
self.add_server_cert(server_cert)
def connect(self):
"""Connect to a host on a given (SSL) port."""
if self.host == '127.0.0.1':
self.host = 'localhost'
sock = socket.create_connection((self.host, self.port),
self.timeout, self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
user_root_cert = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_root_cert = user_root_cert.replace("~", homePath)
result_user_root = 1
if os.path.exists(user_root_cert):
result_user_root = self.connect_trusted_root(sock, user_root_cert,
self.CRL_PATH)
# print 'rur = ',result_user_root
if result_user_root == 1:
glob_root_cert = clVars.Get('cl_glob_root_cert')
result_root_con = 1
if os.path.exists(glob_root_cert):
sock = socket.create_connection((self.host, self.port),
self.timeout,
self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
result_root_con = self.connect_trusted_root(sock,
glob_root_cert,
self.CRL_PATH)
# print 'rrc = ',result_root_con
if result_root_con == 1:
sock = socket.create_connection((self.host, self.port),
self.timeout,
self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
result_server_con = self.connect_trusted_server(
sock, self.CRL_PATH)
# print 'rsc = ',result_server_con
if result_server_con in [1, 2]:
raise Exception
# sys.exit(1)
elif result_root_con == 2:
# sys.exit(1)
raise Exception
elif result_user_root == 2:
# sys.exit(1)
raise Exception
class HTTPSClientAuthHandler(u2.HTTPSHandler):
def __init__(self, key, cert, cert_path):
u2.HTTPSHandler.__init__(self)
self.key = key
self.cert = cert
self.cert_path = cert_path
def https_open(self, req):
# Rather than pass in a reference to a connection class, we pass in
# a reference to a function which, for all intents and purposes,
# will behave as a constructor
return self.do_open(self.getConnection, req)
def getConnection(self, host, timeout=300):
return clientHTTPSConnection(host, key_file=self.key,
cert_file=self.cert,
cert_path=self.cert_path)
class HTTPSClientCertTransport(HttpTransport):
def __init__(self, key, cert, path_to_cert, *args, **kwargs):
HttpTransport.__init__(self, *args, **kwargs)
self.key = key
self.cert = cert
self.cert_path = path_to_cert
def u2open(self, u2request):
"""
Open a connection.
@param u2request: A urllib2 request.
@type u2request: urllib2.Requet.
@return: The opened file-like urllib2 object.
@rtype: fp
"""
tm = self.options.timeout
url = u2.build_opener(HTTPSClientAuthHandler(self.key, self.cert,
self.cert_path))
# from urllib2 import URLError
# try:
if hasattr(self, "u2ver"):
if self.u2ver() < 2.6:
socket.setdefaulttimeout(tm)
return url.open(u2request)
else:
return url.open(u2request, timeout=tm)
else:
return url.open(u2request, timeout=tm)

@ -1,483 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import urllib2 as u2
import os
import sys
import calculate.contrib
from suds.transport.http import HttpTransport
import httplib #http.client in python3
from httplib import HTTPConnection
import socket
import ssl
import hashlib
from calculate.core.datavars import DataVarsCore
from calculate.lib.datavars import DataVars
from calculate.lib.utils.files import readFile
from suds.client import Client
from cert_verify import verify, get_CRL
if hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
else:
ssl_version = None
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
flag = 0
class Client_suds(Client):
def set_parameters(self, path_to_cert, CERT_FILE, PKEY_FILE):
self.path_to_cert = path_to_cert
if not CERT_FILE:
CERT_FILE = ''
self.CERT_FILE = CERT_FILE
self.REQ_FILE = path_to_cert + 'client.csr'
self.PKEY_FILE = PKEY_FILE
self.SID_FILE = path_to_cert + 'sid.int'
self.CRL_PATH = path_to_cert + 'ca/crl/'
if not os.path.exists(self.CRL_PATH):
os.makedirs(self.CRL_PATH)
class clientHTTPSConnection(httplib.HTTPSConnection):
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, cert_path=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
self.cert_path = cert_path
self.CRL_PATH = cert_path + 'ca/crl/'
# get filename store cert server
def cert_list(self, host, ca_certs, server_cert):
if host == '127.0.0.1':
host = 'localhost'
if not os.path.exists(self.trusted_path):
try:
os.makedirs(self.trusted_path)
except OSError:
pass
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
filename = None
try:
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
filename = words[1]
if not filename:
return None
except (IndexError, IOError):
print _("Certificate not found on the client's side")
return None
try:
with open(self.trusted_path + filename, 'r') as fd:
store_cert = fd.read()
if store_cert == server_cert:
return filename
except IOError:
print _("Failed to open the file"), self.trusted_path, filename
return None
def add_all_ca_cert(self, list_ca_certs):
# so root cert be first, ca after
clVarsCore = DataVarsCore()
clVarsCore.importCore()
clVarsCore.flIniFile()
list_ca_certs.reverse()
import OpenSSL
for cert in list_ca_certs:
system_ca_db = clVarsCore.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if cert in readFile(system_ca_db):
continue
clVars = DataVars()
clVars.flIniFile()
homePath = clVars.Get('ur_home_path')
user_root_cert = clVarsCore.Get('cl_user_root_cert')
user_root_cert = user_root_cert.replace("~", homePath)
if os.path.exists(user_root_cert):
if cert in readFile(user_root_cert):
continue
cl_client_cert_dir = clVarsCore.Get('cl_client_cert_dir')
cl_client_cert_dir = cl_client_cert_dir.replace("~", homePath)
root_cert_md5 = cl_client_cert_dir + "/ca/cert_list"
md5 = hashlib.md5()
md5.update(cert)
md5sum = md5.hexdigest()
print "\n================================================="
print "md5sum = ", md5sum
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5, "w")
fc.close()
filename = None
with open(root_cert_md5) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split(' ', 1)
if words[0] == md5sum:
filename = words[1]
if not filename:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
Issuer = certobj.get_issuer().get_components()
for item in Issuer:
if item[0] == 'CN':
filename = item[1]
fc = open(root_cert_md5, "a")
fc.write('%s %s\n' % (md5sum, filename))
fc.close()
if not filename:
print _('Field "CN" not found in the certificate!')
return 1
fd = open(cl_client_cert_dir + '/ca/' + filename, 'w')
fd.write(cert)
fd.close()
fa = open(user_root_cert, 'a')
fa.write(cert)
fa.close()
print _("filename = "), filename
print _("Certificate added")
else:
print _("file containing the CA certificate now exists")
get_CRL(cl_client_cert_dir + '/')
def add_ca_cert(self, cert, list_ca_certs):
url = 'https://%s:%s/?wsdl' % (self.host, self.port)
client = Client_suds(url, transport=HTTPSClientCertTransport(
None, None, self.cert_path))
cert = client.service.get_ca()
if cert == '1':
print _("Invalid server certificate!")
sys.exit()
if cert == '2':
print _("CA certificate not found on the server")
sys.exit()
import OpenSSL
try:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
except (OpenSSL.SSL.Error, IOError):
print _("Error. Certificate not added to the trusted list.")
sys.exit()
print '\n' + _("Fingerprint = %s") % certobj.digest('SHA1')
print _("Serial number = "), certobj.get_serial_number()
Issuer = certobj.get_issuer().get_components()
print '\n' + _("Issuer")
for i in Issuer:
print "%s : %s" % (i[0], i[1])
Subject = certobj.get_subject().get_components()
print '\n' + _("Subject")
for subj in Subject:
print "%s : %s" % (subj[0], subj[1])
ans = raw_input(_("Add the CA certificate to trusted? y/[n]:"))
if ans.lower() in ['y', 'yes']:
list_ca_certs.append(cert)
self.add_all_ca_cert(list_ca_certs)
else:
print _("Certificate not added to trusted")
sys.exit()
# add certificate server in trusted
def add_server_cert(self, cert):
import OpenSSL
print _("Untrusted server certificate!")
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
cert)
print '\n' + _("Fingerprint = %s") % certobj.digest('SHA1')
print _("Serial number = "), certobj.get_serial_number()
Issuer = certobj.get_issuer().get_components()
print '\n' + _("Issuer")
for i in Issuer:
print "%s : %s" % (i[0], i[1])
Subject = certobj.get_subject().get_components()
print '\n' + _("Subject")
for item in Subject:
print "%s : %s" % (item[0], item[1])
print '\n' + _('Add this server certificate to trusted (s) or')
print _('Try to add the CA and root certificates to trusted (c) or')
choice = raw_input(_("Quit (q)? s/c/[q]: "))
if choice.lower() in ['s', 'c']:
# self.sock = ssl.wrap_socket(sock)
ca_certs = self.trusted_path + "cert.list"
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
if self.host == '127.0.0.1':
host = 'localhost'
else:
host = self.host
filename = host
fc = open(self.trusted_path + filename, "w")
fc.write(cert)
fc.close()
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
return 0
# Open file with compliance server certificates and server hostname
fcl = open(ca_certs, "a")
fcl.write(host + ' ' + filename + '\n')
fcl.close()
if choice.lower() == 'c':
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
cl_client_cert_dir = clVars.Get('cl_client_cert_dir')
homePath = clVars.Get('ur_home_path')
cl_client_cert_dir = cl_client_cert_dir.replace("~", homePath)
root_cert_dir = cl_client_cert_dir + "/ca"
if not os.path.exists(root_cert_dir):
try:
os.makedirs(root_cert_dir)
except OSError:
print _("Error creating directory %s") % root_cert_dir
sys.exit()
print '\n' + _("Add the CA and root certificates")
self.list_ca_certs = []
self.add_ca_cert(cert, self.list_ca_certs)
sys.exit()
else:
sys.exit()
def connect_trusted_root(self, sock, root_cert, crl_certs):
self.ca_path = self.cert_path + "ca/"
server_cert = ssl.get_server_certificate(addr=(self.host, self.port))
global flag
if self.cert_file:
f = verify(server_cert, crl_certs, flag)
if not f:
flag = 1
elif f == 1:
sys.exit()
else:
import time
time.sleep(1)
try:
if ssl_version is None:
print _("SSL library is not support TLSv1_2")
self.sock.close()
return 2
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ca_certs=root_cert,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_REQUIRED)
dercert_after_connect = self.sock.getpeercert(True)
cert_after_connect = \
ssl.DER_cert_to_PEM_cert(dercert_after_connect)
if not server_cert == cert_after_connect:
print ('\n' +
_("WARNING! %s trying to replace the certificate!")
% self.host + '\n')
self.sock.close()
return 2
return 0
except Exception:
return 1
def connect_trusted_server(self, sock, crl_certs):
self.trusted_path = self.cert_path + "trusted/"
ca_cert_list = self.trusted_path + "cert.list"
server_cert = ssl.get_server_certificate(addr=(self.host, self.port))
global flag
if self.cert_file:
f = verify(server_cert, crl_certs, flag)
if not f:
flag = 1
elif f == 1:
sys.exit()
HTTPSClientCertTransport.filename = self.cert_list(
self.host, ca_cert_list, server_cert)
if HTTPSClientCertTransport.filename:
try:
if ssl_version is None:
print _("SSL library is not support TLSv1_2")
HTTPSClientCertTransport.filename = None
self.sock.close()
return 1
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_NONE)
dercert_after_connect = self.sock.getpeercert(True)
ssl.DER_cert_to_PEM_cert(dercert_after_connect)
return 0
except Exception as e:
print e
HTTPSClientCertTransport.filename = None
return 1
else:
self.add_server_cert(server_cert)
def connect(self):
"""Connect to a host on a given (SSL) port."""
if self.host == '127.0.0.1':
self.host = 'localhost'
sock = socket.create_connection((self.host, self.port),
self.timeout, self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
user_root_cert = clVars.Get('cl_user_root_cert')
homePath = clVars.Get('ur_home_path')
user_root_cert = user_root_cert.replace("~", homePath)
result_user_root = 1
if os.path.exists(user_root_cert):
result_user_root = self.connect_trusted_root(sock, user_root_cert,
self.CRL_PATH)
# print 'rur = ',result_user_root
if result_user_root == 1:
glob_root_cert = clVars.Get('cl_glob_root_cert')
result_root_con = 1
if os.path.exists(glob_root_cert):
sock = socket.create_connection((self.host, self.port),
self.timeout,
self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
result_root_con = self.connect_trusted_root(sock,
glob_root_cert,
self.CRL_PATH)
# print 'rrc = ',result_root_con
if result_root_con == 1:
sock = socket.create_connection((self.host, self.port),
self.timeout,
self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
result_server_con = self.connect_trusted_server(
sock, self.CRL_PATH)
# print 'rsc = ',result_server_con
if result_server_con in [1, 2]:
raise Exception
# sys.exit(1)
elif result_root_con == 2:
# sys.exit(1)
raise Exception
elif result_user_root == 2:
# sys.exit(1)
raise Exception
class HTTPSClientAuthHandler(u2.HTTPSHandler):
def __init__(self, key, cert, cert_path):
u2.HTTPSHandler.__init__(self)
self.key = key
self.cert = cert
self.cert_path = cert_path
def https_open(self, req):
# Rather than pass in a reference to a connection class, we pass in
# a reference to a function which, for all intents and purposes,
# will behave as a constructor
return self.do_open(self.getConnection, req)
def getConnection(self, host, timeout=300):
return clientHTTPSConnection(host, key_file=self.key,
cert_file=self.cert,
cert_path=self.cert_path)
class HTTPSClientCertTransport(HttpTransport):
def __init__(self, key, cert, path_to_cert, *args, **kwargs):
HttpTransport.__init__(self, *args, **kwargs)
self.key = key
self.cert = cert
self.cert_path = path_to_cert
def u2open(self, u2request):
"""
Open a connection.
@param u2request: A urllib2 request.
@type u2request: urllib2.Requet.
@return: The opened file-like urllib2 object.
@rtype: fp
"""
tm = self.options.timeout
url = u2.build_opener(HTTPSClientAuthHandler(self.key, self.cert,
self.cert_path))
# from urllib2 import URLError
# try:
if hasattr(self, "u2ver"):
if self.u2ver() < 2.6:
socket.setdefaulttimeout(tm)
return url.open(u2request)
else:
return url.open(u2request, timeout=tm)
else:
return url.open(u2request, timeout=tm)

@ -1,136 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import os
import sys
import calculate.contrib
from suds import MethodNotFound
from calculate.core.server.cert_cmd import getHwAddr, getIpLocal
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def get_sid(sid_file):
if not os.path.exists(sid_file):
with open(sid_file, 'w') as fi:
fi.write('0')
sid = 0
else:
with open(sid_file, 'r') as fi:
sid = fi.read()
return sid
def clear():
""" delete caching suds file """
import glob
for filename in glob.glob("/tmp/suds/suds-*"):
try:
os.unlink(filename)
except OSError as e:
print(str(e))
print(_("Failed to clear the cache! "))
return 1
def get_ip_mac_type(client_type=None):
results = [getIpLocal(), getHwAddr()]
if client_type:
results.append(client_type)
else:
results.append('console')
return results
def create_obj(client, method_name):
""" create object indispensable for transfer to the server function """
sd_item = 0
num_port = 0
operation_from_port = 0
inf_param = 1
param_type = 0
ns_name = 0
ns_type = 1
param = 1
pref = ""
sd = client.sd[sd_item]
# get parameter type
operation = sd.ports[num_port][operation_from_port]
info = operation.methods.get(method_name)
if not info:
raise MethodNotFound(method_name)
type_op = info.binding.input.param_defs(info)[param][inf_param]
str_type = type_op.type[param_type]
# get prefix
str_ns = type_op.type[ns_type]
nsprefix = sd.prefixes
# Find a match prefix
for pref_num in range(0, len(nsprefix)):
if str_ns == sd.prefixes[pref_num][ns_type]:
pref = sd.prefixes[pref_num][ns_name]
# Combine in a type
if not pref:
pref = sd.getprefix(str_ns)
for_factory = pref + ":" + str_type
return client.factory.create(for_factory)
def listToArray(client, _list, _type='string'):
array = client.factory.create('%sArray' % _type)
for i in _list:
array['%s' % _type].append(i)
return array
def listToArrayArray(client, _list, _type='string'):
array_array = client.factory.create('%sArrayArray' % _type)
for i in _list:
array = client.factory.create('%sArray' % _type)
for j in i:
array[_type].append(j)
array_array['%sArray' % _type].append(array)
return array_array
class switch(object):
def __init__(self, value):
self.value = value
self.fall = False
def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration
def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False

@ -1,135 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import calculate.contrib
from suds import MethodNotFound
from calculate.core.server.cert_cmd import getHwAddr, getIpLocal
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def get_sid(sid_file):
if not os.path.exists(sid_file):
with open(sid_file, 'w') as fi:
fi.write('0')
sid = 0
else:
with open(sid_file, 'r') as fi:
sid = fi.read()
return sid
def clear():
""" delete caching suds file """
import glob
for filename in glob.glob("/tmp/suds/suds-*"):
try:
os.unlink(filename)
except OSError as e:
print str(e)
print _("Failed to clear the cache! ")
return 1
def get_ip_mac_type(client_type=None):
results = [getIpLocal(), getHwAddr()]
if client_type:
results.append(client_type)
else:
results.append('console')
return results
def create_obj(client, method_name):
""" create object indispensable for transfer to the server function """
sd_item = 0
num_port = 0
operation_from_port = 0
inf_param = 1
param_type = 0
ns_name = 0
ns_type = 1
param = 1
pref = ""
sd = client.sd[sd_item]
# get parameter type
operation = sd.ports[num_port][operation_from_port]
info = operation.methods.get(method_name)
if not info:
raise MethodNotFound(method_name)
type_op = info.binding.input.param_defs(info)[param][inf_param]
str_type = type_op.type[param_type]
# get prefix
str_ns = type_op.type[ns_type]
nsprefix = sd.prefixes
# Find a match prefix
for pref_num in range(0, len(nsprefix)):
if str_ns == sd.prefixes[pref_num][ns_type]:
pref = sd.prefixes[pref_num][ns_name]
# Combine in a type
if not pref:
pref = sd.getprefix(str_ns)
for_factory = pref + ":" + str_type
return client.factory.create(for_factory)
def listToArray(client, _list, _type='string'):
array = client.factory.create('%sArray' % _type)
for i in _list:
array['%s' % _type].append(i)
return array
def listToArrayArray(client, _list, _type='string'):
array_array = client.factory.create('%sArrayArray' % _type)
for i in _list:
array = client.factory.create('%sArray' % _type)
for j in i:
array[_type].append(j)
array_array['%sArray' % _type].append(array)
return array_array
class switch(object):
def __init__(self, value):
self.value = value
self.fall = False
def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration
def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False

@ -1,171 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from __future__ import absolute_import
import sys
from .function import get_sid
client_types = "console"
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def pid_inf(client, sid, pids):
""" get and show information about process """
print("============================")
for pid in pids:
s = client.service.pid_info(sid, pid)
if s == "":
print(_("PID not found"))
return 1
if s[0][0] == "Permission denied":
print(_("Permission denied"))
return 1
print('\n' + _(u"Process name: %s") % s[0][3])
print(_(u"Process ID: %s") % s[0][0])
if s[0][1] == '1':
print(_(u"Process active"))
elif s[0][1] == '0':
print(_(u"Process completed"))
else:
print(_(u"Process killed"))
print(_(u"%s: Process started") % s[0][2])
print("============================")
return 0
def client_list_pid(client):
""" get all process id for this session """
sid = get_sid(client.SID_FILE)
try:
list_pid = client.service.list_pid(sid=sid)
if list_pid[0][0] == 0:
print(_("PIDs not found for this session!"))
return 0
else:
for i in list_pid[0]:
print("pid - %d" % i)
except Exception:
print(_("Failed to get PIDs from the server"))
return 1
return len(list_pid[0])
def gen_pid_ls(client, pid_ls):
""" generation list with pid for this session """
sid = get_sid(client.SID_FILE)
try:
list_pid = client.service.list_pid(sid=sid)
if list_pid[0][0] == 0:
print(_("PIDs not found for this session!"))
return 0
else:
for i in list_pid[0]:
pid_ls.append(i)
except Exception:
print(_("Failed to get PIDs from the server"))
return 0
return pid_ls
def client_pid_info(client):
""" get information about selected process (or about all) """
pid = raw_input(_("PID") + _(": "))
try:
pid = int(pid)
except ValueError:
print(_("PID error"))
return 1
try:
pid_ls = []
pid_get = [pid]
sid = get_sid(client.SID_FILE)
if pid > 0:
pid_inf(client, sid, pid_get)
elif pid == 0:
if gen_pid_ls(client, pid_ls):
pid_inf(client, sid, pid_ls)
except Exception:
print(_("Failed to get data"))
return 1
return 0
def client_list_methods(client):
""" get & show all available methods for this certificate """
DAT = 0 # Access to data soap structure
RES = 0 # Access to result
COM = 0 # Getting command line
METH = 1 # Getting method line
results = client.service.get_methods(client_types)
if not results:
print(_('No methods available'))
return 1
try:
if results[DAT][RES][RES][COM] == '0':
print(_('No methods available'))
return 1
except (IndexError, AttributeError):
pass
print('\n' + _("You can execute:"))
for num in range(0, len(results[DAT])):
print(" %s - %s" % (results[DAT][num][RES][COM],
results[DAT][num][RES][METH]))
def client_list_sessions(client):
""" get all sessions on server """
results = client.service.get_sessions()
if results[0][0] == "Permission denied":
print(results[0][0])
return 1
print(_("Sessions running:"))
for sess in results[0]:
print(" - %s" % sess)
return 0
def client_pid_kill(client):
""" kill process on server """
pid = raw_input(_("PID to be killed: "))
try:
pid = int(pid)
except ValueError:
print(_("PID error"))
return 1
sid = get_sid(client.SID_FILE)
result = client.service.pid_kill(pid, sid)
if result == 0:
print(_(" Killed successfully!"))
elif result == 2:
print(_(" Process completed!"))
elif result == -1:
print(_(" Certificate not found in the server database!"))
elif result == -2:
print(_(" Session not matching your certificate!"))
elif result == 1:
print(_(" Failed to terminate the process!"))

@ -1,169 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from function import get_sid
client_types = "console"
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def pid_inf(client, sid, pids):
""" get and show information about process """
print "============================"
for pid in pids:
s = client.service.pid_info(sid, pid)
if s == "":
print _("PID not found")
return 1
if s[0][0] == "Permission denied":
print _("Permission denied")
return 1
print '\n' + _(u"Process name: %s") % s[0][3]
print _(u"Process ID: %s") % s[0][0]
if s[0][1] == '1':
print _(u"Process active")
elif s[0][1] == '0':
print _(u"Process completed")
else:
print _(u"Process killed")
print _(u"%s: Process started") % s[0][2]
print "============================"
return 0
def client_list_pid(client):
""" get all process id for this session """
sid = get_sid(client.SID_FILE)
try:
list_pid = client.service.list_pid(sid=sid)
if list_pid[0][0] == 0:
print _("PIDs not found for this session!")
return 0
else:
for i in list_pid[0]:
print "pid - %d" % i
except Exception:
print _("Failed to get PIDs from the server")
return 1
return len(list_pid[0])
def gen_pid_ls(client, pid_ls):
""" generation list with pid for this session """
sid = get_sid(client.SID_FILE)
try:
list_pid = client.service.list_pid(sid=sid)
if list_pid[0][0] == 0:
print _("PIDs not found for this session!")
return 0
else:
for i in list_pid[0]:
pid_ls.append(i)
except Exception:
print _("Failed to get PIDs from the server")
return 0
return pid_ls
def client_pid_info(client):
""" get information about selected process (or about all) """
pid = raw_input(_("PID") + _(": "))
try:
pid = int(pid)
except ValueError:
print _("PID error")
return 1
try:
pid_ls = []
pid_get = [pid]
sid = get_sid(client.SID_FILE)
if pid > 0:
pid_inf(client, sid, pid_get)
elif pid == 0:
if gen_pid_ls(client, pid_ls):
pid_inf(client, sid, pid_ls)
except Exception:
print _("Failed to get data")
return 1
return 0
def client_list_methods(client):
""" get & show all available methods for this certificate """
DAT = 0 # Access to data soap structure
RES = 0 # Access to result
COM = 0 # Getting command line
METH = 1 # Getting method line
results = client.service.get_methods(client_types)
if not results:
print _('No methods available')
return 1
try:
if results[DAT][RES][RES][COM] == '0':
print _('No methods available')
return 1
except (IndexError, AttributeError):
pass
print '\n' + _("You can execute:")
for num in range(0, len(results[DAT])):
print " %s - %s" % (results[DAT][num][RES][COM],
results[DAT][num][RES][METH])
def client_list_sessions(client):
""" get all sessions on server """
results = client.service.get_sessions()
if results[0][0] == "Permission denied":
print results[0][0]
return 1
print _("Sessions running:")
for sess in results[0]:
print " - %s" % sess
return 0
def client_pid_kill(client):
""" kill process on server """
pid = raw_input(_("PID to be killed: "))
try:
pid = int(pid)
except ValueError:
print _("PID error")
return 1
sid = get_sid(client.SID_FILE)
result = client.service.pid_kill(pid, sid)
if result == 0:
print _(" Killed successfully!")
elif result == 2:
print _(" Process completed!")
elif result == -1:
print _(" Certificate not found in the server database!")
elif result == -2:
print _(" Session not matching your certificate!")
elif result == 1:
print _(" Failed to terminate the process!")

@ -1,115 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from __future__ import absolute_import
import sys
from .function import get_sid
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def client_sid(sid, client, cert_id):
""" get number session from server and write this in file """
# lang = raw_input ("Enter language (ru, en, de, fr): ")
lang = "ru"
new_sid = client.service.post_sid(sid=sid, cert_id=cert_id, lang=lang)
fi = open(client.SID_FILE, 'w')
sid = str(new_sid[0][0])
fi.write(sid)
fi.close()
if new_sid[0][1] == 1:
print(_(" New session"))
else:
print(_(" Old session"))
print(_(" Your session ID = %s") % sid)
def client_del_sid(client):
""" delete this session """
sid = get_sid(client.SID_FILE)
try:
s = client.service.del_sid(sid)
if s[0][0] == "-1":
print(_("No access to the file!"))
return -1
if s[0][0] == "1":
print(_("Failed to obtain the certificate data!"))
return -2
if s[0][0] == "Permission denied":
print(_("%s: Permission denied") % s[1][1])
return -3
if s[0][0] == '0':
fi = open(client.SID_FILE, 'w')
fi.write('0')
fi.close()
print(_("SID deleted!"))
except Exception:
print(_("Failed to delete the SID on the server"))
return 1
return 0
def sid_inf(client, sid):
""" get information about selected session """
s = client.service.sid_info(sid)
if s[0][0] == "-1":
print(_("Session not registered on the server!"))
return -1
if s[0][0] == "-2":
print(_("Failed to obtain the certificate data!"))
return -2
if s[0][0] == "Permission denied":
print(_("%s: Permission denied") % s[0][1])
return -3
print("============================")
print('\n' + _(u"Session number: %s") % sid)
if s[0][5] == "0":
print(_(u"Session active"))
else:
print(_(u"Session inactive"))
print(_(u"Certificate number: %s") % s[0][0])
print(_(u"Certificate issued on %s") % s[0][1])
print(_(u"IP: %s") % s[0][2])
print(_(u"MAC: %s") % s[0][3])
print(_(u"Client type: %s") % s[0][4])
print("============================")
return 0
def client_session_info(client):
""" select session for get information """
sid = raw_input("SID: ")
try:
sid = int(sid)
except ValueError:
print(_("Invalid SID"))
return 1
try:
if sid > 0:
sid_inf(client, sid)
else:
print(_("Please enter a correct SID"))
except Exception:
print(_("Failed to get data"))
return 1
return 0

@ -1,113 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from function import get_sid
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def client_sid(sid, client, cert_id):
""" get number session from server and write this in file """
# lang = raw_input ("Enter language (ru, en, de, fr): ")
lang = "ru"
new_sid = client.service.post_sid(sid=sid, cert_id=cert_id, lang=lang)
fi = open(client.SID_FILE, 'w')
sid = str(new_sid[0][0])
fi.write(sid)
fi.close()
if new_sid[0][1] == 1:
print _(" New session")
else:
print _(" Old session")
print _(" Your session ID = %s") % sid
def client_del_sid(client):
""" delete this session """
sid = get_sid(client.SID_FILE)
try:
s = client.service.del_sid(sid)
if s[0][0] == "-1":
print _("No access to the file!")
return -1
if s[0][0] == "1":
print _("Failed to obtain the certificate data!")
return -2
if s[0][0] == "Permission denied":
print _("%s: Permission denied") % s[1][1]
return -3
if s[0][0] == '0':
fi = open(client.SID_FILE, 'w')
fi.write('0')
fi.close()
print _("SID deleted!")
except Exception:
print _("Failed to delete the SID on the server")
return 1
return 0
def sid_inf(client, sid):
""" get information about selected session """
s = client.service.sid_info(sid)
if s[0][0] == "-1":
print _("Session not registered on the server!")
return -1
if s[0][0] == "-2":
print _("Failed to obtain the certificate data!")
return -2
if s[0][0] == "Permission denied":
print _("%s: Permission denied") % s[0][1]
return -3
print "============================"
print '\n' + _(u"Session number: %s") % sid
if s[0][5] == "0":
print _(u"Session active")
else:
print _(u"Session inactive")
print _(u"Certificate number: %s") % s[0][0]
print _(u"Certificate issued on %s") % s[0][1]
print _(u"IP: %s") % s[0][2]
print _(u"MAC: %s") % s[0][3]
print _(u"Client type: %s") % s[0][4]
print "============================"
return 0
def client_session_info(client):
""" select session for get information """
sid = raw_input("SID: ")
try:
sid = int(sid)
except ValueError:
print _("Invalid SID")
return 1
try:
if sid > 0:
sid_inf(client, sid)
else:
print _("Please enter a correct SID")
except Exception:
print _("Failed to get data")
return 1
return 0

@ -1,66 +0,0 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# from server.cl_server import main
# print(main)
def core_main():
import sys
if hasattr(sys, "setdefaultencoding"):
sys.setdefaultencoding("utf-8")
from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_core', sys.modules[__name__])
from traceback import print_exc
from os import path
if not path.exists('/dev/urandom'):
sys.stderr.write("/dev/urandom not found\n")
sys.exit(1)
try:
from server.cl_server import main
reload(sys)
from calculate.lib.datavars import CriticalError, DataVarsError
try:
sys.exit(main())
except (CriticalError, DataVarsError) as e:
sys.stderr.write("%s\n" % str(e))
sys.exit(1)
except ImportError as e:
print_exc()
cannot_import = 'cannot import name '
no_module = 'No module named '
if e.message.startswith(cannot_import):
print (_('Failed to import %s')
% e.message.rpartition(cannot_import)[2])
elif e.message.startswith(no_module):
print (_('No module named %s') %
e.message.rpartition(no_module)[2])
else:
print e.message
sys.exit(1)
except KeyboardInterrupt:
print
print _("Task interrupted")
if (__name__ == "__main__"):
core_main()

@ -1,691 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2011-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from itertools import cycle
from calculate.lib.utils.colortext import get_terminal_print, Terminal, \
TextState, convert_xml_to_terminal, Print
from calculate.lib.cl_progressbar import get_progress_bar
import sys
from calculate.lib.utils.files import getch, set_active_tty, get_active_tty
from calculate.lib.utils.text import tableReport
import threading
from calculate.lib.utils.tools import classificate
Colors = TextState.Colors
from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
class Spinner(threading.Thread):
def __init__(self, *args, **kwargs):
self.__halt = threading.Event()
self.__main_thread = threading.currentThread()
threading.Thread.__init__(self, *args, **kwargs)
self.start()
def run(self):
Terminal().cursor = False
try:
sys.stdout.write(" |")
for c in cycle('/-\|'):
sys.stdout.write('\b' + c)
sys.stdout.flush()
self.__halt.wait(0.2)
sys.stdout.flush()
if self.__halt.is_set():
sys.stdout.write('\b\b \b\b')
return
if not self.__main_thread.is_alive():
return
finally:
Terminal().cursor = True
def stop(self):
self.__halt.set()
self.join()
class Table(tableReport):
def __init__(self, *args, **kwargs):
self.res = []
tableReport.__init__(self, *args, **kwargs)
def printFunc(self, s):
self.res.append(s)
def printTable(self):
self.setAutosize()
self.printReport(printRows=False)
return "".join(self.res)
def printTable(data, header=None):
try:
if any(data):
return Table(None, header, data, colSpan=0).printTable()
else:
return ""
except Exception:
# print str(e)
raise
def echo_on(f):
def wrapper(self, *args, **kw):
oldecho = self.parent.terminal_info.echo
self.parent.terminal_info.echo = True
try:
return f(self, *args, **kw)
finally:
self.parent.terminal_info.echo = oldecho
return wrapper
class TaskState(object):
"""
Текущее состояние вывода сообщений
"""
def __init__(self, parent):
self.parent = parent
@property
def state(self):
return self.parent.task_state
def process_tags(self, s):
"""
Выполнить текстовое преобразование
"""
s = s or ""
return convert_xml_to_terminal(s).replace("&nbsp;", " ")
def display_asterisk(self, color):
"""
Отобразить маркер
"""
self.parent.printer(" ")
self.parent.printer.foreground(color).bold("*")
self.parent.printer(" ")
def _right_indent(self, indent, width=-1):
"""
Выполнить выравнивание от правого края
"""
if width > 0:
self.parent.printer('\r')
self.parent.printer.right(width - indent)
else:
self.parent.printer(" ")
def _change_asterisk(self, color, width=-1):
if width > 0:
self.parent.printer('\r')
self.display_asterisk(color)
def dotting(self):
if self.parent.spinner:
self.parent.spinner.stop()
self.parent.printer(" ...")
self.parent.printer.flush()
def _print_result(self, text, color):
width = self.parent.terminal_info.width
self._change_asterisk(color, width)
self._right_indent(len(text) + 4, width)
self.parent.printer.bold.foreground(TextState.Colors.BLUE)("[ ")
self.parent.printer.bold.foreground(color)(text)
self.parent.printer.bold.foreground(TextState.Colors.BLUE)(" ]")
self.parent.printer("\n")
def _print_ok(self):
self._print_result("ok", TextState.Colors.GREEN)
def _print_failed(self):
self._print_result("!!", TextState.Colors.RED)
def _print_skip(self):
self._print_result("skip", TextState.Colors.YELLOW)
def display_result(self, result):
func_map = {"skip": self._print_skip,
False: self._print_failed}
func_map.get(result, self._print_ok)()
self.parent.printer.flush()
def startTask(self, message, progress, num):
pass
def endTask(self, result, progress_message=None):
pass
def breakTask(self):
pass
def printMessage(self, color, message):
for i, line in classificate(self.process_tags(message).split('\n')):
self.display_asterisk(color)
self.parent.printer(line)
if not i.last:
self.parent.printer('\n')
try:
self.parent.printer.flush()
except IOError:
pass
def printERROR(self, message):
self.printMessage(Colors.RED, message)
def printSUCCESS(self, message):
self.printMessage(Colors.GREEN, message)
def printWARNING(self, message):
self.printMessage(Colors.YELLOW, message)
def startGroup(self, message):
self.parent.printer.foreground(Colors.WHITE)(self.process_tags(message))
self.parent.printer('\n')
def endGroup(self):
pass
def beginFrame(self, message):
self.parent.terminal_info.echo = False
def endFrame(self):
self.parent.terminal_info.echo = True
def addProgress(self, message):
pass
def setProgress(self, percent, short_message, long_message):
pass
@echo_on
def askConfirm(self, message, default):
self.parent.printer("\n")
while True:
try:
_print = Print(output=self.parent.printer.output)
if default in "yes":
yes_color, no_color = Colors.GREEN, Colors.LIGHT_RED
else:
yes_color, no_color = Colors.LIGHT_RED, Colors.GREEN
yes = _print.foreground(yes_color)("Yes")
no = _print.foreground(no_color)("No")
white_message = _print.foreground(Colors.WHITE)(message)
ask = raw_input(white_message + ' (%s/%s): ' % (yes, no))
except (EOFError, KeyboardInterrupt):
ask = 'no'
print
if ask.lower() in ['n', 'no']:
return "no"
if ask.lower() in ['y', 'yes']:
return "yes"
if ask == '':
return default
def printPre(self, message):
self.parent.printer(self.process_tags(message))
self.parent.printer('\n')
def printDefault(self, message):
self.parent.printer(self.process_tags(message))
self.parent.printer('\n')
@echo_on
def askChoice(self, message, answers):
self.parent.printer("\n")
Colors = TextState.Colors
printer = self.parent.printer
_print = Print(output=printer.output)
# ability answer by first letter
firstletter = 0
i_value, i_comment = 0, 1
answerByChar = map(lambda x: x[i_value][firstletter], answers)
if filter(lambda x: answerByChar.count(x) > 1, answerByChar):
use_getch = False
sa = slice(0, None)
else:
use_getch = True
sa = slice(1)
message = _print.foreground(Colors.WHITE)(message)
full_message = (message +
' (%s): ' % ("/".join(map(
lambda x: "%s[%s]" % (x[i_comment], x[i_value][sa]),
answers))))
while True:
CTRC_C = chr(3)
if use_getch:
printer(full_message)
ask = getch()
printer("\n")
if ask in (CTRC_C, ""):
raise KeyboardInterrupt
else:
try:
ask = raw_input(full_message)
except (EOFError, KeyboardInterrupt):
printer("\n")
raise KeyboardInterrupt
ask = ask.lower()
like_answers = filter(lambda x: x[i_value].startswith(ask),
answers)
if not like_answers:
self.state.printERROR(_('The answer is uncertain'))
continue
if len(like_answers) == 1:
return like_answers[i_value][firstletter]
else:
self.state.printERROR(_('Ambiguous answer:') +
",".join(map(lambda x: x[i_comment],
like_answers)))
@echo_on
def askQuestion(self, message):
self.parent.printer("\n")
return raw_input(message + _(":"))
def askPassword(self, message, twice):
from calculate.lib.utils.common import getpass
old_tty = None
try:
if self.parent.terminal_info.is_boot_console():
old_tty = get_active_tty()
set_active_tty(1)
text1 = _("%s: ") % message
if not twice:
return getpass.getpass(text1)
text2 = _('Repeat: ')
pass1 = 'password'
pass2 = 'repeat'
try:
while pass1 != pass2:
pass1 = getpass.getpass(text1)
pass2 = getpass.getpass(text2)
if pass1 != pass2:
self.state.printERROR(_('Passwords do not match'))
except KeyboardInterrupt:
return None
passwd = pass1 if (pass1 and pass1 == pass2) else None
return passwd
finally:
if old_tty and old_tty.isdigit():
set_active_tty(int(old_tty))
def printTable(self, table_name, head, body):
self.state.printSUCCESS(message=table_name)
self.parent.printer(printTable(body, head))
class CleanState(TaskState):
"""
Ожидается вывод
"""
def startTask(self, message, progress, num):
self.printMessage(Colors.GREEN, message)
self.parent.spinner = Spinner()
self.parent.set_state('start')
if progress:
self.parent.addProgress()
def printERROR(self, message):
super(CleanState, self).printERROR(message)
self.parent.printer('\n')
def printSUCCESS(self, message):
super(CleanState, self).printSUCCESS(message)
self.parent.printer('\n')
def printWARNING(self, message):
super(CleanState, self).printWARNING(message)
self.parent.printer('\n')
class CleanStateNoProgress(CleanState):
"""
... без отображения прогрессов
"""
def startTask(self, message, progress, num):
self.display_asterisk(Colors.GREEN)
self.parent.printer(message)
self.dotting()
self.parent.set_state('start')
class StartState(TaskState):
"""
Выполняется задача (отображается spinner)
"""
def startTask(self, message, progress, num):
self.parent.endTask(True)
self.parent.startTask(message, progress, num)
def endTask(self, result, progress_message=None):
self.dotting()
self.parent.set_state('clean')
self.display_result(result)
def breakTask(self):
self.dotting()
self.parent.set_state('clean')
self.parent.printer('\n')
def printERROR(self, message):
self.dotting()
self.parent.printer('\n')
self.parent.set_state('clean')
self.state.printERROR(message)
def printSUCCESS(self, message):
self.dotting()
self.parent.set_state('breaked')
self.state.printSUCCESS(message)
def printWARNING(self, message):
self.dotting()
self.parent.set_state('breaked')
self.state.printWARNING(message)
def startGroup(self, message):
self.state.endTask(True)
self.state.startGroup(message)
def endGroup(self):
self.state.endTask(True)
self.state.endGroup()
def beginFrame(self, message):
self.state.endTask(True)
self.state.beginFrame(message)
def endFrame(self):
self.state.endTask(True)
self.state.endFrame()
def addProgress(self, message):
self.parent.set_state("pre-progress")
self.state.addProgress(message)
def printPre(self, message):
self.parent.endTask(True)
self.state.printPre(message)
def printDefault(self, message):
self.state.endTask(True)
self.state.printDefault(message)
def askChoice(self, message, answers):
self.breakTask()
return self.state.askChoice(message, answers)
def askQuestion(self, message):
self.breakTask()
return self.state.askQuestion(message)
def askPassword(self, message, twice):
self.breakTask()
return self.state.askPassword(message, twice)
def askConfirm(self, message, default):
self.breakTask()
return self.state.askConfirm(message, default)
def printTable(self, table_name, head, body):
self.breakTask()
self.state.printTable(table_name, head, body)
class StartStateNoProgress(StartState):
"""
... без прогресса
"""
def startTask(self, message, progress, num):
self.parent.endTask(True)
self.parent.startTask(message, progress, num)
def endTask(self, result, progress_message=None):
self.parent.set_state('clean')
self.display_result(result)
def breakTask(self):
self.parent.printer('\n')
def printERROR(self, message):
self.breakTask()
self.parent.set_state('clean')
self.state.printERROR(message)
def printSUCCESS(self, message):
self.breakTask()
self.parent.set_state('clean')
self.state.printSUCCESS(message)
def printWARNING(self, message):
self.breakTask()
self.parent.set_state('clean')
self.state.printWARNING(message)
def addProgress(self, message):
pass
class BreakedState(StartState):
"""
Во время выполнения задачи выведено сообщение
"""
def stop_spinner_newline(self):
self.parent.spinner.stop()
self.parent.printer('\n')
def startTask(self, message, progress, num):
self.state.endTask(True)
self.state.startTask(message, progress, num)
def breakTask(self):
self.stop_spinner_newline()
self.parent.set_state('clean')
def endTask(self, result, progress_message=None):
self.breakTask()
def printERROR(self, message):
self.parent.endTask(True)
self.state.printERROR(message)
def printSUCCESS(self, message):
self.stop_spinner_newline()
TaskState.printSUCCESS(self, message)
self.parent.spinner = Spinner()
def printWARNING(self, message):
self.stop_spinner_newline()
TaskState.printWARNING(self, message)
self.parent.spinner = Spinner()
class PreProgressState(StartState):
"""
Задача запрошена как с прогрессом но проценты еще не обрабатывались
"""
def addProgress(self, message):
pass
def setProgress(self, percent, short_message, long_message):
self.parent.set_state("progress")
self.dotting()
self.parent.printer("\n")
self.parent.add_progressbar()
self.parent.terminal_info.cursor = False
self.state.setProgress(percent, short_message, long_message)
class ProgressState(StartState):
"""
Отображается progressbar
"""
def finish_and_clean(self):
self.parent.printer('\r')
self.parent.printer.flush()
self.parent.progress.finish()
self.parent.terminal_info.cursor = True
self.parent.set_progressbar(None)
self.parent.printer.up(1).clear_line("")
self.parent.printer.up(1)("")
def setProgress(self, percent, short_message, long_message):
if not 0 <= percent <= 100:
self.breakTask()
else:
self.parent.progress.update(percent)
def breakTask(self):
self.finish_and_clean()
self.parent.set_state('clean')
self.parent.printer('\n')
def endTask(self, result, progress_message=None):
self.finish_and_clean()
self.parent.set_state('clean')
self.display_result(result)
def printERROR(self, message):
self.finish_and_clean()
self.parent.printer.down(1)("")
self.parent.set_state('clean')
self.state.printERROR(message)
def printSUCCESS(self, message):
self.finish_and_clean()
self.parent.set_state('breaked')
self.state.printSUCCESS(message)
def printWARNING(self, message):
self.finish_and_clean()
self.parent.set_state('breaked')
self.state.printWARNING(message)
class ResultViewer(object):
"""
Просмотрщик результатов
"""
def __init__(self):
self.printer = \
get_terminal_print(sys.stdout)
self.terminal_info = Terminal()
self.states = {'clean': CleanState(self),
'breaked': BreakedState(self),
'pre-progress': PreProgressState(self),
'progress': ProgressState(self),
'start': StartState(self)}
self.task_state = self.states['clean']
self.spinner = None
self.progress = None
self.no_questions = False
def set_no_progress(self):
self.states = {'clean': CleanStateNoProgress(self),
'start': StartStateNoProgress(self)}
self.set_state('clean')
def set_no_questions(self):
self.no_questions = True
def set_state(self, state):
self.task_state = self.states[state]
def add_progressbar(self):
self.set_progressbar(get_progress_bar())
def set_progressbar(self, pb):
self.progress = pb
def endTask(self, result=None, progress_message=None):
self.task_state.endTask(result, progress_message)
def startTask(self, message, progress=False, num=1):
self.task_state.startTask(message, progress, num)
def printERROR(self, message, onlyShow=None):
if onlyShow != 'gui':
self.task_state.printERROR(message)
def printSUCCESS(self, message, onlyShow=None):
if onlyShow != 'gui':
self.task_state.printSUCCESS(message)
def printWARNING(self, message, onlyShow=None):
if onlyShow != 'gui':
self.task_state.printWARNING(message)
def startGroup(self, message):
self.task_state.startGroup(message)
def endGroup(self):
self.task_state.endGroup()
def beginFrame(self, message=None):
self.task_state.beginFrame(message)
def endFrame(self):
self.task_state.endFrame()
def addProgress(self, message=None):
self.task_state.addProgress(message)
def setProgress(self, percent, short_message=None, long_message=None):
self.task_state.setProgress(percent, short_message, long_message)
def printPre(self, message, onlyShow=None):
if onlyShow != 'gui':
self.task_state.printPre(message)
def printDefault(self, message='', onlyShow=None):
if onlyShow != 'gui':
self.task_state.printDefault(message)
def askConfirm(self, message, default="yes"):
if self.no_questions:
return default
return self.task_state.askConfirm(message, default)
def askChoice(self, message, answers=(("yes", "Yes"), ("no", "No"))):
return self.task_state.askChoice(message, answers)
def askPassword(self, message, twice=False):
return self.task_state.askPassword(message, twice)
def askQuestion(self, message):
return self.task_state.askQuestion(message)
def printTable(self, table_name, head, body, fields=None,
onClick=None, addAction=None, step=None, records=None):
self.task_state.printTable(table_name, head, body)

@ -1,128 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2011-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from calculate.lib.cl_progressbar import get_progress_bar, get_message_box
from calculate.lib.utils.colortext import TextState
import sys
from result_viewer import PreProgressState, ProgressState
Colors = TextState.Colors
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
class PreProgressStateGui(PreProgressState):
"""
Задача запрошена как с прогрессом но проценты еще не обрабатывались
"""
def addProgress(self, message):
self.dotting()
self.parent.printer("\n")
self.parent.add_progressbar()
self.parent.set_state("progress")
class ProgressStateGui(ProgressState):
"""
Отображение для gui прогресса
"""
def finish_and_clean(self):
self.parent.progress.finish()
self.parent.printer.up(1)("")
self.parent.set_progressbar(None)
class ResultViewerDecorator(object):
def __init__(self, rv):
self.rv = rv
for v in self.rv.states.values():
v.parent = self
def __getattr__(self, item):
return getattr(self.rv, item)
class ProgressGui(ResultViewerDecorator):
"""
Отображение прогресса в Qt диалогах
"""
def __init__(self, rv):
super(ProgressGui, self).__init__(rv)
self.rv.states['pre-progress'] = PreProgressStateGui(self)
self.rv.states['progress'] = ProgressStateGui(self)
self.progress_title = ""
def add_progressbar(self):
self.set_progressbar(get_progress_bar("gui", self.progress_title))
def startTask(self, message, progress=False, num=1):
self.rv.startTask(message, progress, num)
self.progress_title = message
class ErrorGui(ResultViewerDecorator):
"""
Отображение ошибок через gui
"""
def __init__(self, rv):
super(ErrorGui, self).__init__(rv)
self.messages = []
def show_messages(self):
get_message_box().critical("\n".join(self.messages).decode('utf-8'))
def printERROR(self, message, onlyShow=None):
self.rv.printERROR(message, onlyShow)
if onlyShow != 'gui':
if message:
self.messages.append(message)
def endFrame(self):
self.rv.task_state.endFrame()
if self.messages:
self.show_messages()
class WarningGui(ResultViewerDecorator):
"""
Отображение предупреждений через gui
"""
def __init__(self, rv):
super(WarningGui, self).__init__(rv)
self.warnings = []
def show_messages(self):
get_message_box().warning("\n".join(self.warnings).decode('utf-8'))
def printWARNING(self, message, onlyShow=None):
self.rv.printWARNING(message, onlyShow)
if onlyShow != 'gui':
if message:
self.warnings.append(message)
def endFrame(self):
self.rv.task_state.endFrame()
if not self.messages and self.warnings:
self.show_messages()
elif self.messages:
self.messages.extend(self.warnings)
self.rv.show_messages()

@ -1,873 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from calculate.core.server.loaded_methods import LoadedMethods
import calculate.contrib
from spyne import String, Integer, Boolean
from spyne.model.primitive import string_encoding
from spyne import Array, ComplexModel
# from spyne.model import Mandatory
from spyne import rpc
import sys
import pickle
import os
from calculate.lib.datavars import SourceReadonlyVariable
from calculate.core.server.core_interfaces import CoreServiceInterface
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
String.Attributes.encoding = "utf-8"
#####
# API
#####
class CommonInfo(ComplexModel):
"""
Common info for all Info classes
cl_templates_locate - templates location
cl_dipatch_conf - update config method
cl_verbose_set - display appling templates
"""
cl_templates_locate = Array(String)
cl_dispatch_conf = String
cl_verbose_set = Boolean
Default = Array(String)
CheckAll = Boolean
class LazyString(object):
pass
class DataVarsSerializer(ComplexModel):
"""Serializer for datavars types"""
class Attributes(ComplexModel.Attributes):
default = None
min_occurs = 1
def elementByType(self, typeobj):
"""Get element by variable type, given for table or not"""
elementMap = {'table': 'table',
"string": "input",
"bool": "check",
"boolauto": "check_tristate",
"bool3": "check_tristate",
"choice": "combo",
"choiceedit": "comboEdit",
"choiceedit-list": "multichoice_add",
"choice-list": "multichoice",
"bool-list": "multichoice",
"list": "multichoice_add",
"password": "password",
"onepassword": "password",
"need-onepassword": "password",
"need-password": "password"}
return elementMap.get(typeobj, 'input')
def arrayString(self, value):
if type(value) in (list, tuple):
return [""] + map(lambda x: (",".join(x)
if type(x) in (list, tuple)
else x),
value)
else:
return value
def arrayArrayString(self, value):
if type(value) in (list, tuple):
return map(self.arrayString, value)
else:
return value
def getChoice(self, var_obj):
if ("choice" in var_obj.type or "file" in var_obj.type or
var_obj.element == "radio"):
choice, comments = var_obj.parent.ChoiceAndComments(var_obj.name)
return self.arrayString(choice), self.arrayString(comments)
else:
return None, None
class ChoiceValue(DataVarsSerializer):
typefield = String(default=None, min_occurs=1)
values = Array(String, default=None, min_occurs=1)
comments = Array(String, default=None, min_occurs=1)
onChanged = Array(String, default=None, min_occurs=1)
def __init__(self, dv=None, varObj=None, readOnly=False, **kwargs):
if dv:
super(ChoiceValue, self).__init__()
if not readOnly:
self.values, self.comments = self.getChoice(varObj)
elif isinstance(varObj, SourceReadonlyVariable):
items = varObj.getMapHumanReadable().items()
if items:
self.values, self.comments = zip(*items)
else:
self.values, self.comments = [], []
self.values = self.arrayString(self.values)
self.comments = self.arrayString(self.comments)
if varObj.mode == 'w':
self.typefield = (varObj.element or
self.elementByType(varObj.type))
else:
if readOnly:
self.typefield = "readonly"
else:
self.typefield = "text"
else:
super(ChoiceValue, self).__init__(**kwargs)
def elementByType(self, typeobj):
"""Get element by variable type, given for table or not"""
if "-list" in typeobj:
typeobj = typeobj.replace("-list", "", 1)
elif "list" in typeobj:
typeobj = typeobj.replace("list", "", 1)
return DataVarsSerializer.elementByType(self,
typeobj)
class Table(DataVarsSerializer):
# head = Mandatory(Array(String(default=None, min_occurs=1), min_occurs=1))
head = Array(String(default=None, min_occurs=1), min_occurs=1)
fields = Array(String(default=None, min_occurs=1), min_occurs=1) # name fields in params object
body = Array(Array(String), default=None, min_occurs=1)
values = Array(ChoiceValue, default=None, min_occurs=1)
onClick = String(default=None, min_occurs=1)
addAction = String(default=None, min_occurs=1)
# шаг на который нужно прейти при выполнении onClick
step = String(default=None, min_occurs=1)
# количество записей в таблице
records = String(default=None, min_occurs=1)
def __init__(self, dv=None, briefmode=None,
varObj=None, head=None, body=None, values=None,
fields=None, onClick=None, addAction=None, step=None,
records=None):
super(Table, self).__init__()
# print("DEBUG Table init")
if dv:
self.head = []
self.body = []
self.values = []
# get information about all table columns
self.writable = True
for i, col in enumerate(varObj.source):
# get columns variable obj
varSource = dv.getInfo(col)
# invalidate columns vars for uncompatible table
if varSource.uncompatible():
dv.Invalidate(col, onlySet=True)
# header label
self.head.append(varSource.label or varSource.name)
# if column writable then add ChoiceValue info
if varSource.mode == 'w' or i == 0:
self.values.append(ChoiceValue(dv, varSource))
if varSource.mode == 'r' and i == 0:
self.writable = False
else:
self.values.append(
ChoiceValue(dv, varSource, readOnly=True))
# get table body
# empty value at start add for fix data transfer
self.body = self.arrayArrayString(
dv.Get(varObj.name, humanreadable=True if briefmode else False))
else:
self.head = head
self.fields = fields
self.body = body
self.values = values
self.onClick = onClick
self.addAction = addAction
self.step = step or "0"
self.records = records or "0"
class Option(DataVarsSerializer):
shortopt = String(default=None, min_occurs=1)
longopt = String(default=None, min_occurs=1)
metavalue = String(default=None, min_occurs=1)
syntax = String(default=None, min_occurs=1)
help = String(default=None, min_occurs=1)
def __init__(self, optlist, metaval, helpval, syntax=""):
super(Option, self).__init__()
self.help = helpval
self.metavalue = metaval
self.syntax = syntax
for val in optlist:
if val.startswith('--'):
self.longopt = val
else:
self.shortopt = val
class Field(DataVarsSerializer):
name = String(default=None, min_occurs=1) # varname from Datavars
label = String(default=None, min_occurs=1) # label for GUI
type = String(default=None, min_occurs=1) # data type of variable
opt = Option # opt for cmdline
help = String(default=None, min_occurs=1) # help for cmdline (GUI?)
element = String(default=None, min_occurs=1) # type element
guitype = String(default=None, min_occurs=1) # addon guitype
choice = Array(String, default=None, min_occurs=1) # value (combobox,comboedit)
listvalue = Array(String, default=None, min_occurs=1) # current listvalue
default = Boolean(default=None, min_occurs=1) # default value or False
value = String(default=None, min_occurs=1) # current value
tablevalue = Table # current table value
uncompatible = String(default=None, min_occurs=1) # message for uncompatibility variable
comments = Array(String, default=None, min_occurs=1) # comments for choice
def __init__(self, dv=None, varObj=None, expert=False, briefmode=False,
inbrief=False, groupVars=(), onlyhelp=False, **kwargs):
"""
dv - datavars, varObj - current variable, expert - expert variable flag,
briefmode - view request for brief, inbrief - variable palced in brief,
"""
if dv:
super(Field, self).__init__()
self.name = varObj.name
self.type = varObj.type
if varObj.opt:
self.opt = Option(varObj.opt, varObj.metavalue, varObj.help,
varObj.syntax)
self.help = varObj.help
self.element = varObj.element or self.elementByType(self.type)
self.label = str(varObj.label or varObj.name)
self.guitype = varObj.guitype
if (not onlyhelp or varObj.syntax or self.type == "table" or
self.type == "bool"):
if inbrief:
self.uncompatible = ""
else:
self.uncompatible = dv.Uncompatible(varObj.name)
if self.uncompatible:
# блок используется для отмены пометки о несовместимости
# если несовместимая переменная, и та из-за которой
# она является несовместимой находятся на одной и той же
# странице (например доступность MBR зависит от опции UEFI,
# они находятся на одной и той же странице)
for var in varObj.reqUncompat:
if not briefmode and var in groupVars:
if not dv.Uncompatible(var.name):
self.uncompatible = ""
break
else:
dv.Invalidate(varObj.name, onlySet=True)
if expert:
self.default = not varObj.wasSet
self.choice, self.comments = self.getChoice(varObj)
if self.type == "table":
# print("DEBUG_table creation")
self.tablevalue = Table(dv=dv, briefmode=briefmode,
varObj=varObj)
if self.tablevalue.writable:
self.type = "writable"
else:
full_varname = "%s.%s" % (varObj.section, varObj.name)
value = dv.Get(full_varname)
if type(value) in (list, tuple):
if briefmode and "choice" not in self.type:
self.value = dv.Get(full_varname,
humanreadable=True)
self.listvalue = self.arrayString(value)
else:
if briefmode: # and not "choice" in self.type:
self.value = dv.Get(full_varname,
humanreadable=True)
else:
self.value = value
# if self.value:
# self.default = self.value
else:
super(Field, self).__init__(**kwargs)
class GroupField(DataVarsSerializer):
name = String(default=None, min_occurs=1)
fields = Array(Field, default=None, min_occurs=1)
prevlabel = String(default=None, min_occurs=1)
nextlabel = String(default=None, min_occurs=1)
last = Boolean(default=None, min_occurs=1)
def __init__(self, name="", fields=list(), prevlabel="",
nextlabel="", last=False, dv=None, info=None,
expert=False, brief=False, onlyhelp=False):
super(GroupField, self).__init__()
self.last = last
if dv:
self.name = info['name']
if not onlyhelp:
self.nextlabel = info['next_label']
self.prevlabel = _("Previous")
else:
self.nextlabel = None
self.prevlabel = None
self.fields = []
# get all variables with deps which using in this group
groupDepVars = []
from itertools import chain
for varname in chain(info['normal'], info['expert']):
for var in dv.getRequired(varname):
if var not in groupDepVars:
groupDepVars.append(var)
if brief:
uniqBrief = list(info['brief']) + [x for x in
info['brief_force']
if x not in info['brief']]
for varname in uniqBrief:
varObj = dv.getInfo(varname)
inbrief = varname in info['brief_force']
self.fields.append(Field(dv=dv, inbrief=inbrief,
briefmode=brief,
varObj=varObj,
groupVars=groupDepVars,
onlyhelp=onlyhelp))
else:
uniqBrief = []
for varname in (x for x in info['normal'] if x not in uniqBrief):
inbrief = brief and varname in info['brief_force']
if brief and 'hide' in info and varname in info['hide']:
continue
varObj = dv.getInfo(varname)
self.fields.append(Field(dv=dv, inbrief=inbrief,
briefmode=brief,
varObj=varObj,
groupVars=groupDepVars,
onlyhelp=onlyhelp))
if info['expert']:
for varname in (x for x in info['expert'] if
x not in uniqBrief):
if expert is True or expert is None and dv.getInfo(
varname).wasSet:
self.fields.append(Field(name="expert",
element="expert",
label=str(info['expert_label']),
value="open"))
for varname_ in info['expert']:
inbrief = brief and varname_ in info['brief_force']
if (brief and 'hide' in info and
varname_ in info['hide']):
continue
varObj = dv.getInfo(varname_)
self.fields.append(Field(dv=dv, expert=True,
inbrief=inbrief,
briefmode=brief,
varObj=varObj,
groupVars=groupDepVars,
onlyhelp=onlyhelp))
break
else:
if expert is False:
for varname in info['expert']:
vn = varname.rpartition('.')[2]
dv.Invalidate(vn, True)
if not onlyhelp:
self.fields.append(Field(name="expert",
element="expert",
label=str(info['expert_label']),
value="close",
onlyhelp=onlyhelp))
else:
self.name = name
self.fields = fields
self.nextlabel = nextlabel
class ViewInfo(DataVarsSerializer):
groups = Array(GroupField, default=None, min_occurs=1)
has_brief = Boolean(default=None, min_occurs=1)
def __init__(self, datavars=None, step=None, expert=None, allsteps=False,
brief=None, brief_label=None, has_brief=False, groups=list(),
viewparams=None):
super(ViewInfo, self).__init__()
onlyhelp = False
if viewparams:
# for compatible specifing step by param
step = viewparams.step if step is None else step
expert = viewparams.expert if expert is None else expert
brief = viewparams.brief if brief is None else brief
onlyhelp = viewparams.onlyhelp
self.has_brief = has_brief
if datavars:
self.groups = []
varGroups = datavars.getGroups()
lastGroup = len(varGroups) - 1
# interate all vars group
if step in (0, -1, None) or allsteps:
briefData = datavars.getBrief()
# print("DEBUG viewInfo")
# print("var groups: %s " % bool(varGroups))
# print(datavars)
self.groups.append(self.stepGroup(varGroups, brief_label,
help_value=briefData.get(
"help", None),
next_value=briefData.get(
"next", None),
image_value=briefData.get(
"image", "")))
for i, groupInfo in enumerate(varGroups):
if step in (None, -1) or step == i:
# print("viewInfo step %s " % i)
self.groups.append(GroupField(dv=datavars, info=groupInfo,
last=(lastGroup == i),
expert=expert,
brief=brief,
onlyhelp=onlyhelp))
if groupInfo['custom_buttons']:
for but in groupInfo['custom_buttons']:
if len(but) > 4:
listval = but[4]
else:
listval = None
if len(but) > 5:
f = but[5]
if f is None or callable(f) and f(datavars.Get):
enable = True
else:
enable = False
else:
enable = True
self.groups[-1].fields.append(Field(
name=but[0], label=but[1], value=but[2],
element=but[3], listvalue=listval,
guitype=None if enable else "readonly"))
else:
self.groups = groups
def stepGroup(self, groupInfo, brief_label, help_value=None,
next_value=None, image_value=""):
"""Step group"""
# print("DEBUG what are you doing stepGroup")
# print(groupInfo)
# print(brief_label)
return GroupField(fields=[
Field(name="Steps",
element="table",
label=brief_label,
type='steps',
help=help_value,
value=next_value,
tablevalue=Table(
head=[i['name'] for i in groupInfo],
fields=[i.get('image', '')
for i in groupInfo] + [image_value],
body=[self.arrayString(
list(i['normal']) + [""] + list(i['expert']))
for i in groupInfo]))])
# element = ['table', 'radio', 'combo', 'comboEdit', 'multichoice', \
# 'multichoice_add', 'check', 'check_tristate', 'expert', 'input']
class ViewParams(ComplexModel):
"""
Struct for _view methods
"""
step = Integer(default=None, min_occurs=1) # number of group variables
expert = Boolean(default=None, min_occurs=1) # request expert variables
brief = Boolean(default=None, min_occurs=1) # request brief variables
onlyhelp = Boolean(default=None, min_occurs=1) # request params for only help
help_set = Boolean(default=None, min_occurs=1) # set cl_help_set to on
conargs = Array(String, default=None, min_occurs=1) # set cl_console_args
dispatch_usenew = Boolean(default=None, min_occurs=1) # set cl_dispatch_conf to usenew
clienttype = String(default=None, min_occurs=1) # type of client "gui","console"
#########
# MESSAGE
#########
class ReturnedMessage(ComplexModel):
type = String(default=None, min_occurs=1)
field = String(default=None, min_occurs=1)
message = String(default=None, min_occurs=1)
expert = Boolean(default=None, min_occurs=1)
field_obj = Field
def __init__(self, type=None, field=None, message=None,
expert=False, field_obj=None):
super(ReturnedMessage, self).__init__()
self.type = type
self.field = field
self.message = message
self.expert = expert
if field_obj:
self.field_obj = Field(dv=field_obj.parent, varObj=field_obj)
else:
self.field_obj = None
class Message(ComplexModel):
type = String(default=None, min_occurs=1)
message = String(default=None, min_occurs=1)
id = Integer(default=None, min_occurs=1)
result = Boolean(default=None, min_occurs=1)
onlyShow = String(default=None, min_occurs=1)
default = String(default=None, min_occurs=1)
def __init__(self, type='normal', message=None, id=None,
result=None, onlyShow=None, default=None):
super(Message, self).__init__()
self.type = type
self.message = message
self.id = id
self.result = result
self.onlyShow = onlyShow
self.default = default
class ReturnProgress(ComplexModel):
percent = Integer(default=None, min_occurs=1)
short_message = String(default=None, min_occurs=1)
long_message = String(default=None, min_occurs=1)
control = Integer(default=None, min_occurs=1)
def __init__(self, percent=0, short_message=None, long_message=None,
control=None):
super(ReturnProgress, self).__init__()
self.percent = percent
self.short_message = short_message
self.long_message = long_message
self.control = control
class Frame(ComplexModel):
values = Array(Message, default=None, min_occurs=1)
# get and send client messages
class CoreWsdl(CoreServiceInterface):
perm_denied = [Message(type='error', message='403 Forbidden')]
@staticmethod
def callAction(cls, sid, info, logicClass=None,
method_name=None, actionClass=None,
callbackRefresh=lambda sid, dv: True,
invalidators=None, depend_methods=()):
"""
Общий алгоритм вызова действия
"""
if not logicClass:
logicClass = {}
dv = cls.get_cache(sid, method_name, "vars")
try:
if not dv:
dv = getattr(cls, "%s_vars" % method_name)()
else:
callbackRefresh(cls, sid, dv)
dv.processRefresh()
checkonly = False
checkall = False
if info and hasattr(info, "CheckOnly"):
checkonly = info.CheckOnly
if info and not hasattr(info, "CheckOnly"):
checkall = True
elif info and hasattr(info, "CheckAll"):
checkall = info.CheckAll
errors = map(lambda x: ReturnedMessage(**x),
dv.checkGroups(info,
allvars=checkall or not checkonly,
invalidators=invalidators))
# if dv.Get('cl_env_debug_set') == 'on':
# dv.printGroup(info)
if errors:
return errors
if checkonly:
returnmess = ReturnedMessage(type='', message=None)
return [returnmess]
if not actionClass:
return []
objs = {}
from calculate.core.server.func import CommonLink
if isinstance(logicClass, dict):
for k, v in logicClass.items():
objs[k] = type("Logic", (CommonLink, v, object), {})()
install_meth = type("CommonCore", (cls.Common,
actionClass, object), {})
pid = cls.startprocess(cls, sid, target=install_meth,
method="run",
method_name=method_name,
args_proc=(objs, dv,))
returnmess = ReturnedMessage(type='pid', message=pid)
returnmess.type = "pid"
returnmess.message = pid
cls.clear_cache(sid, method_name)
cache_cleared = [method_name]
clear_list = list(LoadedMethods.methodDepends[method_name])
while clear_list:
method_clear_name = clear_list.pop()
if method_clear_name not in cache_cleared:
clear_list.extend(
LoadedMethods.methodDepends[method_clear_name])
cls.clear_cache_method(method_clear_name)
cache_cleared.append(method_clear_name)
dv = None
return [returnmess]
finally:
if dv:
# print "Set cache", dv.Get('ur_unix_group_name_exists')
cls.set_cache(sid, method_name, "vars", dv, smart=False)
@staticmethod
def fixInstallLocalization(cls, sid, dv):
"""
Метод смены локализации интерфейса на лету (во время выбора
параметров метода)
"""
# print("DEBUG fixInstallLocalization")
# print(dv)
if "--start" not in sys.argv:
return False
import threading
curThread = threading.currentThread()
curThread.lang = dv.Get('install.os_install_locale_lang')
# print("LOCALE DEBUG: thread lang: %s" % curThread.lang)
currentLang = cls.get_cache(sid, "install", "lang")
# print("LOCALE DEBUG: cached lang: %s" % currentLang)
if currentLang != curThread.lang:
dv.clearGroups()
cls.install_vars(cls, dv)
dv.reinit()
return True
else:
return False
# verification of compliance certificate and process (pid)
@staticmethod
def check_cert_pid(cls, sid, pid):
import threading
curThread = threading.currentThread()
cert = curThread.client_cert
from cert_cmd import find_cert_id
cert_id = find_cert_id(cert, cls.data_path, cls.certbase)
cert_id = int(cert_id)
if cert_id == 0:
return 0
# session file
if not os.path.exists(cls.sids):
os.system('mkdir %s' % cls.sids)
check = 0
try:
fd = open(cls.sids_file, 'r')
except IOError:
return 0
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
break
# find session id in sids file
if cert_id == int(list_sid[1]):
if sid == int(list_sid[0]):
check = 1
if check == 0:
return 0
fd = open(cls.sids_pids, 'r')
while 1:
try:
# read out on 1 record
list_pid = pickle.load(fd)
except (EOFError, KeyError, IOError):
break
if sid == int(list_pid[0]):
if pid == int(list_pid[1]):
fd.close()
return 1
fd.close()
return 0
# send to client all new message
@staticmethod
def process_messages(cls, pid, client_type):
result = []
while len(cls.glob_frame_list[pid]) > \
cls.glob_process_dict[pid]['counter']:
item = cls.glob_process_dict[pid]['counter']
only_show = cls.glob_frame_list[pid][item].onlyShow
if (not client_type or
not only_show or only_show == client_type):
result.append(cls.glob_frame_list[pid][item])
cls.glob_process_dict[pid]['counter'] += 1
return result
# send to client new message from frame
@staticmethod
def client_get_frame(cls, sid, pid, client_type):
if cls.check_cert_pid(cls, sid, pid):
return cls.process_messages(cls, pid, client_type)
return CoreWsdl.perm_denied
# send to client new message from frame
@staticmethod
def client_get_entire_frame(cls, sid, pid):
if cls.check_cert_pid(cls, sid, pid):
try:
results = cls.glob_frame_list[pid]
except (AttributeError, KeyError, IndexError):
return CoreWsdl.perm_denied
len_glob_frame_list = len(cls.glob_frame_list[pid])
cls.glob_process_dict[pid]['counter'] = len_glob_frame_list
return results
return CoreWsdl.perm_denied
@staticmethod
def client_get_table(cls, sid, pid, id):
if cls.check_cert_pid(cls, sid, pid):
return cls.glob_table_dict[pid][id]
return CoreWsdl.perm_denied
@staticmethod
def client_get_progress(cls, sid, pid, id):
if cls.check_cert_pid(cls, sid, pid):
return cls.glob_progress_dict[pid][id]
return ReturnProgress(0, control=403)
@staticmethod
# get message from client
def client_send_message(cls, sid, pid, text):
if cls.check_cert_pid(cls, sid, pid):
cls.glob_process_dict[pid]['answer'] = text
return Message(type='normal', message="")
return CoreWsdl.perm_denied
class WsdlAdapter(object):
adapted_class = None
def __init__(self, source):
self.source = source
@classmethod
def from_detect(cls, source):
if isinstance(source, (cls.adapted_class, WsdlAdapter)):
return source
else:
return cls(source)
def __getattr__(self, item):
return getattr(self.source, item)
@staticmethod
def Array(field, field_type):
def wrapper(self):
if getattr(self.source, field):
return [field_type(x)
for x in getattr(getattr(self.source, field),
field_type.__name__[:-7])]
else:
return []
return property(wrapper)
@staticmethod
def StringArray(field):
def wrapper(self):
source_field = getattr(self.source, field)
return source_field.string if source_field else []
return property(wrapper)
class ChoiceValueAdapter(WsdlAdapter):
adapted_class = ChoiceValue
values = WsdlAdapter.StringArray("values")
comments = WsdlAdapter.StringArray("comments")
onChanged = WsdlAdapter.StringArray("onChanged")
class TableAdapter(WsdlAdapter):
adapted_class = Table
fields = WsdlAdapter.StringArray("fields")
head = WsdlAdapter.StringArray("head")
@classmethod
def get_matrix(cls, value):
if hasattr(value, 'stringArray'):
return [row.string
for row in value.stringArray
if hasattr(row, "string")]
elif isinstance(value, list):
return value
return []
@property
def body(self):
return self.get_matrix(self.source.body)
values = WsdlAdapter.Array("values", ChoiceValueAdapter)
class FieldAdapter(WsdlAdapter):
adapted_class = Field
choice = WsdlAdapter.StringArray("choice")
listvalue = WsdlAdapter.StringArray("listvalue")
comments = WsdlAdapter.StringArray("comments")
@property
def tablevalue(self):
return TableAdapter(self.source.tablevalue)
class GroupFieldAdapter(WsdlAdapter):
adapted_class = GroupField
fields = WsdlAdapter.Array("fields", FieldAdapter)
class ViewInfoAdapter(WsdlAdapter):
adapted_class = ViewInfo
groups = WsdlAdapter.Array("groups", GroupFieldAdapter)
class ArrayReturnedMessage(WsdlAdapter):
@classmethod
def from_detect(cls, source):
if isinstance(source, (list, tuple)):
return source
else:
return source.ReturnedMessage

@ -1,404 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import calculate.contrib
from spyne import rpc
from spyne import Service
from spyne import String, Integer, Array
from calculate.core.server.core_interfaces import CoreServiceInterface
from calculate.lib.utils.files import readFile
_ = lambda x: x
from calculate.lib.cl_lang import getLazyLocalTranslate, setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
from clean import sid_monitor, monitor
from tasks import restart, dbus_stop
from loaded_methods import LoadedMethods
from api_types import Message, ReturnProgress, Table
import post_cert
import post_request
import send_cert
String.Attributes.encoding = "utf-8"
# class Basic(CoreServiceInterface):
class Basic(Service, CoreServiceInterface):
""" Basic server class """
SERV_VERS = 0.11
glob_process_dict = {}
process_pid = {}
glob_progress_dict = {}
glob_table_dict = {}
glob_frame_list = {}
manager = None
data_path = None
certbase = None
rights = None
sids = None
pids = None
sids_file = None
ssl_certificate = None
ssl_private_key = None
cachedict = {}
#workaround: Spyne won't let us use self ref in @rpc,
# and ctx leads to original service class (Basic in this case)
# but some methods are gathered from CoreWsdl classes, so we need
# a ref to combined class
comb_class_ref = None
# function getting object from cache
@staticmethod
def get_cache(sid, meth_name, obj_name):
if sid in Basic.cachedict:
if meth_name in Basic.cachedict[sid]:
if obj_name in Basic.cachedict[sid][meth_name]:
return Basic.cachedict[sid][meth_name][obj_name]
return None
# function placing object in cache
@staticmethod
def set_cache(sid, meth_name, obj_name, obj, smart=True):
try:
if sid not in Basic.cachedict:
Basic.cachedict[sid] = {}
if meth_name not in Basic.cachedict[sid]:
Basic.cachedict[sid][meth_name] = {}
if obj_name not in Basic.cachedict[sid][meth_name]:
Basic.cachedict[sid][meth_name][obj_name] = obj
return True
if smart:
for var_name, var_value in obj.__dict__.viewitems():
if var_value is not None:
setattr(Basic.cachedict[sid][meth_name][obj_name],
var_name, var_value)
else:
Basic.cachedict[sid][meth_name][obj_name] = obj
return True
except Exception as e:
if isinstance(e, SyntaxError):
raise
return False
@staticmethod
def clear_cache(sid, meth_name=None, obj_name=None):
if sid not in Basic.cachedict:
return True
if meth_name:
if meth_name not in Basic.cachedict[sid]:
return True
if obj_name:
if obj_name not in Basic.cachedict[sid][meth_name]:
return True
else:
obj = Basic.cachedict[sid][meth_name].pop(obj_name, None)
if hasattr(obj, 'close'):
obj.close()
else:
method_dict = Basic.cachedict[sid].pop(meth_name, None)
for val_obj in method_dict.values():
if hasattr(val_obj, 'close'):
val_obj.close()
else:
session_dict = Basic.cachedict.pop(sid, None)
for method_dict in session_dict.values():
for val_obj in method_dict.values():
if hasattr(val_obj, 'close'):
val_obj.close()
@staticmethod
def clear_cache_method(method=None):
for k, v in Basic.cachedict.items():
Basic.clear_cache(k, method)
@staticmethod
def set_paths(data_path, certbase, serv_certbase, rights,
group_rights, sids, pids, sids_pids, sids_file, pids_file,
max_sid, max_pid, cert_path, log_filename,
cert="server.crt", key="server.key"):
""" set system path for main class """
Basic.data_path = data_path
Basic.certbase = certbase
Basic.serv_certbase = serv_certbase
Basic.rights = rights
Basic.group_rights = group_rights
Basic.sids = sids
Basic.pids = pids
Basic.sids_pids = sids_pids
Basic.sids_file = sids_file
Basic.pids_file = pids_file
Basic.ssl_certificate = cert
Basic.ssl_private_key = key
Basic.cert_path = cert_path
Basic.max_sid = int(max_sid)
Basic.max_pid = int(max_pid)
Basic.log_filename = log_filename
@staticmethod
def set_comb_class_ref(comb_class_ref):
Basic.comb_class_ref = comb_class_ref
@staticmethod
def run_tasks():
"""
Запуситить регулярные задачи
"""
import threading
# start monitor and sid_monitor threads
monitoring = threading.Thread(target=monitor,
args=(Basic.certbase, Basic.sids_file))
sid_mon = threading.Thread(target=sid_monitor,
args=(Basic.sids_file, Basic.sids, Basic.comb_class_ref))
restart_watchdog = threading.Thread(target=restart,
args=(Basic.comb_class_ref.glob_process_dict,))
dbus_stop_mon = threading.Thread(target=dbus_stop,
args=(Basic.comb_class_ref.glob_process_dict, Basic.comb_class_ref.sids, Basic.comb_class_ref))
threads = []
for thread, success, failed in (
(monitoring, _("General monitoring started"),
_("Monitoring error")),
(sid_mon, _("Session monitoring started"),
_("Session monitoring failed")),
(restart_watchdog, _("Restart watchdog started"),
_("Restart watchdog failed")),
(dbus_stop_mon, _("Inactive watchdog started"),
_("Inactive watchdog failed"))):
try:
threads.append(thread)
thread.daemon = True
thread.start()
print success
except Exception:
print failed
print
@staticmethod
def killall():
sys.stdout.write('\n' + _('Closing all processes') + '...')
sys.stdout.flush()
import time
# Waiting for closing
for pid in Basic.process_pid.keys():
try:
os.kill(Basic.process_pid[pid].pid, 2)
except OSError:
pass
while True:
num_active_process = 0
for pid in Basic.process_pid.keys():
if Basic.process_pid[pid].is_alive():
num_active_process += 1
if num_active_process:
sys.stdout.write('.')
sys.stdout.flush()
else:
print '\n' + _('All processes are closed.')
return 0
time.sleep(0.5)
@rpc(_returns=Array(Integer))
def post_cert(ctx):
# import post_cert
returns = post_cert.serv_post_cert(Basic.comb_class_ref)
return returns
@rpc(Integer, _returns=Integer)
def clear_session_cache(ctx, sid):
check_sid = Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid)
if not check_sid:
return 1
# clear cache
Basic.clear_cache(sid)
return 0
@rpc(Integer, String, _returns=Integer)
def clear_method_cache(ctx, sid, method_name):
check_sid = Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid)
if not check_sid:
return 1
# clear cache
Basic.clear_cache(sid, method_name)
return 0
@rpc(Integer, Integer, _returns=Integer)
def clear_pid_cache(ctx, sid, pid):
if not Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid):
return 1
if pid in Basic.comb_class_ref.find_sid_pid_file(Basic.comb_class_ref, sid):
# clear pid cache
Basic.comb_class_ref.delete_pid(Basic.comb_class_ref, sid, pid)
return 0
return 2
@rpc(Integer, Integer, String, _returns=Array(Integer))
def post_sid(self, sid, cert_id, lang):
return Basic.comb_class_ref.sid_cmp(Basic.comb_class_ref, sid, cert_id, lang)
@rpc(Integer, String, _returns=(Array(Integer), Array(Integer)))
def init_session(ctx, sid, lang):
return Basic.comb_class_ref.serv_init_session(Basic.comb_class_ref, sid, lang)
@rpc(Integer, _returns=Array(String))
# @Dec.check_permissions(['del_sid'])
def del_sid(self, sid):
flag = Basic.comb_class_ref.del_sid_pid(Basic.comb_class_ref, sid)
Basic.comb_class_ref.clear_cache(int(sid))
if not flag:
return Basic.comb_class_ref.del_sid_from_file(Basic.comb_class_ref,
sid)
else:
return ['-1']
@rpc(Integer, Integer, _returns=Integer)
def pid_kill(ctx, pid, sid):
return Basic.comb_class_ref.serv_pid_kill(Basic.comb_class_ref, pid, sid)
@rpc(Integer, _returns=Array(Integer))
def list_pid(ctx, sid):
return Basic.comb_class_ref.find_sid_pid_file(Basic.comb_class_ref, sid)
@rpc(Integer, String, _returns=Array(Array(String)))
def get_methods(ctx, sid, client_type):
return map(lambda x: map(str, x),
Basic.comb_class_ref.serv_get_methods(Basic.comb_class_ref, client_type))
@rpc(Integer, _returns=Array(String))
@LoadedMethods.core_method(rights=["get-sessions"])
# @Dec.console('list-session')
def get_sessions(ctx, sid):
if not Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid):
return ['']
return Basic.comb_class_ref.serv_get_sessions(Basic.comb_class_ref)
@rpc(Integer, Integer, _returns=Array(String))
# @Dec.check_permissions(["pid_info"])
def pid_info(ctx, sid, pid):
return Basic.comb_class_ref.serv_pid_info(Basic.comb_class_ref, sid, pid)
@rpc(Integer, _returns=Array(String))
@LoadedMethods.core_method(rights=["session_info"])
def sid_info(ctx, sid):
return Basic.comb_class_ref.serv_sid_info(Basic.comb_class_ref, sid)
@rpc(Integer, String, _returns=Array(String))
@LoadedMethods.check_permissions(["view_cert_right"])
# @Dec.console('view-cert-right')
# @Dec.gui('System')
def view_cert_right(ctx, cert_id, client_type):
return Basic.comb_class_ref.serv_view_cert_right(Basic.comb_class_ref,
cert_id, Basic.data_path, client_type)
@rpc(Integer, _returns=Integer)
def active_client(ctx, sid):
return Basic.comb_class_ref.active_clients(Basic.comb_class_ref, sid)
@rpc(String, String, String, String, _returns=String)
def post_client_request(ctx, request, ip, mac, client_type):
res = post_request.serv_post_client_request(request, Basic.data_path,
ip, mac, client_type,
Basic.certbase,
Basic.cert_path)
return res
@rpc(String, String, _returns=Array(String))
def get_client_cert(ctx, req_id, request):
res = post_request.serv_get_client_cert(req_id, request,
Basic.data_path, Basic.certbase,
Basic.cert_path)
return res
@rpc(String, String, String, _returns=String)
def post_server_request(ctx, request, ip, mac):
res = post_request.serv_post_server_request(request, Basic.data_path,
ip, mac, Basic.serv_certbase,
Basic.cert_path)
return res
@rpc(String, String, _returns=Array(String))
def get_server_cert(ctx, req_id, request):
res = post_request.serv_get_server_request(req_id, request,
Basic.data_path,
Basic.serv_certbase,
Basic.cert_path)
return res
@rpc(_returns=String)
def get_crl(self):
if os.path.exists(Basic.data_path + '/server_certs/ca.crl'):
return readFile(Basic.data_path + '/server_certs/ca.crl')
return ' '
@rpc(_returns=String)
def get_server_host_name(ctx):
import OpenSSL
cert = readFile(Basic.ssl_certificate)
cert_obj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
subject = cert_obj.get_subject().get_components()
for subj in subject:
if subj[0] == 'CN':
return subj[1]
return ''
@rpc(_returns=String)
def get_ca(ctx):
return send_cert.get_ca(Basic.cert_path)
#moved here from api_types:
@rpc(Integer, Integer, String, _returns=Array(Message))
# @Dec.check_permissions()
def get_frame(ctx, sid, pid, client_type):
return Basic.comb_class_ref.client_get_frame(Basic.comb_class_ref, sid, pid, client_type)
@rpc(Integer, Integer, _returns=Array(Message))
def get_entire_frame(self, sid, pid):
return Basic.comb_class_ref.client_get_entire_frame(Basic.comb_class_ref, sid, pid)
@rpc(Integer, Integer, Integer, _returns=ReturnProgress)
# @Dec.check_permissions()
def get_progress(self, sid, pid, id):
return Basic.comb_class_ref.client_get_progress(Basic.comb_class_ref, sid, pid, id)
@rpc(Integer, Integer, Integer, _returns=Table)
# @Dec.check_permissions()
def get_table(self, sid, pid, id):
return Basic.comb_class_ref.client_get_table(Basic.comb_class_ref, sid, pid, id)
# get messages, transferred from client
@rpc(Integer, Integer, String, _returns=Message)
# @Dec.check_permissions()
def send_message(self, sid, pid, text):
return Basic.comb_class_ref.client_send_message(Basic.comb_class_ref, sid, pid, text)

@ -1,499 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import cert_cmd
import post_request
import datetime
import subprocess
import shutil
from calculate.core.client.cert_func import new_key_req
from calculate.core.client.function import get_ip_mac_type
from calculate.core.datavars import DataVarsCore
from calculate.lib.utils.files import (makeDirectory, pathJoin, readFile,
writeFile, readFileEx)
from calculate.lib.utils.mount import isMount
from calculate.core.server.admin import Admins
import os
import hashlib
import pwd
import socket
import sys
import re
_ = lambda x: x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3', sys.modules[__name__])
def parse_cert_date(date):
year = int(date[:4])
month = int(date[4:6])
day = int(date[6:8])
hour = int(date[8:10])
minute = int(date[10:12])
sec = int(date[12:14])
return datetime.datetime(year, month, day, hour, minute, sec)
def check(cert, key):
error_flag = 0
if not os.path.isfile(cert):
error_flag = 1
print _('Certificate %s not found') % cert
print key, cert
if not os.path.isfile(key):
error_flag = 1
print _('Private key %s not found') % key
if os.path.isfile(cert) and os.path.isfile(key):
import OpenSSL
# check correspondence certificate and private key
cmd_cert = 'openssl x509 -noout -modulus -in ' + cert
cmd_key = 'openssl rsa -noout -modulus -in ' + key
p_cert = subprocess.Popen(cmd_cert.split(), stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p_key = subprocess.Popen(cmd_key.split(), stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if not p_cert.stdout.read().strip() == p_key.stdout.read().strip():
print _('The certificate does not match the private key')
error_flag = 1
# check certificate date
cert_data = readFile(cert)
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert_data)
certobj.get_notBefore()
try:
not_after = parse_cert_date(certobj.get_notAfter())
not_before = parse_cert_date(certobj.get_notBefore())
date = datetime.datetime.now()
if not_before > date:
print _('Certificate creation date later than current date')
error_flag = 1
elif not_after < date:
print _('Certificate expired')
error_flag = 1
except ValueError:
print _('Failed to get certificate work date')
error_flag = 1
sys.exit(error_flag)
def init(cert, key, cert_path, data_path, certbase, args, port):
if args.remove_certificates:
key_force(cert_path, data_path)
new_serv_cert = False
if not check_serv_cert(cert_path):
print _('Generating the server certificate')
for step in range(2):
args = change_args(args, step)
create_server_cert(cert, key, cert_path, args, port)
new_serv_cert = True
else:
print _('Server certificate now exists.')
os.chmod(data_path, 0700)
def force_user_cert(server_cert, cert_path, data_path, cert_base, user_name,
dv=None):
def is_crypthome_notmount(dv, username):
dv.Set('ur_login', user_name, force=True)
homedir = dv.Get('ur_home_path')
if (dv.GetBool('ur_home_crypt_set') and
'.Private' not in isMount(homedir)):
return True
return False
if not check_client_cert(user_name, server_cert=server_cert):
print _('Generating the client certificate')
else:
print _('Regenerating the client certificate')
group = "all"
if dv:
admins = Admins(dv)
if user_name not in admins:
admins[user_name] = group
admins.save()
group = admins[user_name]
if is_crypthome_notmount(dv, user_name):
print _("User profile is encrypted. Please perform user login for "
"complete of certificate generation")
return
create_client_cert(server_cert, cert_path, data_path, cert_base,
user_name, group)
def check_serv_cert(cert_path):
if os.path.isfile(os.path.join(cert_path, 'server.crt')) and \
os.path.isfile(os.path.join(cert_path, 'server.key')):
return True
return False
def check_client_cert(user_name, server_cert=None):
client_cert_path = check_user_path(user_name)
if server_cert:
server_host_name = get_certificate_dn(server_cert)
else:
server_host_name = socket.getfqdn()
crt_fn = os.path.join(client_cert_path, server_host_name + '.crt')
key_fn = os.path.join(client_cert_path, server_host_name + '.key')
if os.path.isfile(crt_fn) and os.path.isfile(key_fn):
return True
return False
def change_args(args, step=None):
if step == 0:
args.host = False
args.gen_root_cert = True
args.root_host = False
args.use_root_cert = False
elif step == 1:
args.gen_root_cert = False
args.use_root_cert = True
return args
def create_server_cert(cert, key, cert_path, args, port):
cert_cmd.check_server_certificate(cert, key, cert_path, args, port,
auto=True)
def create_client_cert(server_cert, cert_path, data_path, certbase, user_name,
group="all"):
client_cert_path = check_user_path(user_name)
if not client_cert_path:
print _('no path to the client certificate')
return 1
req_id = create_request(server_cert, cert_path, data_path, certbase,
client_cert_path, user_name)
sign_certificate(req_id, cert_path, data_path, group)
get_certificate(cert_path, data_path, certbase, client_cert_path, user_name,
server_cert=server_cert)
def check_user_path(user_name):
try:
pwdObj = pwd.getpwnam(user_name)
except KeyError as e:
print e
return None
home_dir = pwdObj.pw_dir
if not os.path.isdir(home_dir):
if not makeDirectory(home_dir):
return None
os.chown(home_dir, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(home_dir, 0700)
calc_dir = os.path.join(home_dir, '.calculate')
cert_dir = os.path.join(calc_dir, 'client_cert')
for directory in [calc_dir, cert_dir]:
if not os.path.isdir(directory):
if not makeDirectory(directory):
return None
os.chown(directory, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(directory, 0755)
for path in os.walk(cert_dir):
os.chown(path[0], pwdObj.pw_uid, pwdObj.pw_gid)
for _file in path[2]:
fn = pathJoin(path[0], _file)
if os.path.isfile(fn):
os.chown(fn, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(fn, 0644)
return cert_dir
def create_request(server_cert, cert_path, data_path, certbase,
client_cert_path, user_name):
server_host_name = get_certificate_dn(server_cert)
key = os.path.join(client_cert_path, server_host_name + '.key')
client_req_file = new_key_req(key, client_cert_path, server_host_name,
auto=True)
try:
pwdObj = pwd.getpwnam(user_name)
except KeyError as e:
print e
return None
for files in [client_req_file, key + '_pub']:
if os.path.exists(files):
os.chown(files, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(files, 0644)
if os.path.exists(key):
os.chown(key, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(key, 0600)
ip, mac, client_type = get_ip_mac_type()
data = readFile(client_req_file)
req_id = post_request.serv_post_client_request(
data, data_path, ip, mac, client_type, certbase, cert_path)
fc = open(os.path.join(client_cert_path, 'req_id'), 'w')
fc.write(req_id)
fc.close()
return req_id
def sign_certificate(req_id, cert_path, data_path, group="all"):
cert_cmd.sing_req_by_server(req_id, cert_path, data_path, auto=True,
group_name=group)
def get_certificate_dn(cert_file):
cert_data = readFile(cert_file)
if cert_data:
import OpenSSL
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert_data)
cert_info = dict(certobj.get_subject().get_components())
return cert_info["CN"]
return "localhost"
def clear_localuser_certificates(certbase):
"""
Удалить все пользовательские сертификаты, создаваемые для локальных
пользователей
"""
certdata = readFileEx(certbase, grab=True)
certdn = os.path.dirname(certbase)
# оставляем только сертификаты, которые не содержат отметки
# для какого локального пользователя они созданы
writedata = "\n".join(x[0] for x in re.findall("^((\S+\s+){6}\S+)\s*$",
certdata, flags=re.M))
with writeFile(certbase) as f:
f.write("%s\n"%writedata)
# удаляем физически сертификаты, созданные для локальных пользователей
for localcert in re.finditer("^(\S+)\s+(\S+\s+){6}\S+\s*$",
certdata, flags=re.M):
cert_fn = "%s/%s.crt"%(certdn, localcert.group(1))
try:
os.unlink(cert_fn)
except OSError:
print _("Failed to remove local client certificate") % cert_fn
def get_certificate(cert_path, data_path, certbase, client_cert_path,
user_name, server_cert=None):
req_id_file = os.path.join(client_cert_path, 'req_id')
if not os.path.exists(req_id_file):
print _("request not sent or file %s deleted") % req_id_file
return 1
fc = open(req_id_file, 'r')
req_id = fc.read()
fc.close()
if server_cert:
server_host_name = get_certificate_dn(server_cert)
else:
server_host_name = socket.getfqdn()
req_file = os.path.join(client_cert_path, server_host_name + '.csr')
if not os.path.exists(req_file):
print _('Request %s not found') % req_file
return 1
request = readFile(req_file)
md5 = hashlib.md5()
md5.update(request)
md5sum = md5.hexdigest()
result = post_request.serv_get_client_cert(
req_id, md5sum, data_path, certbase, cert_path,
localuser=user_name)
cert = result[0]
if len(result) > 1:
ca_root = result[1]
else:
return None
if cert == '1':
print _('The signature request was rejected!')
return 1
elif cert == '2':
print _("The signature request has not been examined yet.")
print _("Your request ID = %s") % req_id
return 1
elif cert == '3':
print _("The signature request does not match earlier data.")
return 1
elif cert == '4':
print _("The request was sent from another IP.")
return 1
cert_file = os.path.join(client_cert_path, server_host_name + '.crt')
fc = open(cert_file, 'w')
fc.write(cert)
fc.close()
try:
pwdObj = pwd.getpwnam(user_name)
except KeyError, e:
print e
return None
os.chown(cert_file, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(cert_file, 0600)
os.unlink(req_id_file)
print _('Certificate saved. Your certificate ID: %s') % req_id
if ca_root:
clVars = DataVarsCore()
clVars.importCore()
clVars.flIniFile()
system_ca_db = clVars.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if ca_root in readFile(system_ca_db):
return 0
ca_dir = os.path.join(client_cert_path, 'ca')
if not os.path.isdir(ca_dir):
os.makedirs(ca_dir)
os.chown(ca_dir, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(ca_dir, 0755)
root_cert_md5 = os.path.join(ca_dir, "cert_list")
md5 = hashlib.md5()
md5.update(ca_root)
md5sum = md5.hexdigest()
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5, "w")
fc.close()
filename = None
with open(root_cert_md5) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split(' ', 1)
if words[0] == md5sum:
filename = words[1]
if not filename:
import OpenSSL
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, ca_root)
issuer = certobj.get_issuer().get_components()
for item in issuer:
if item[0] == 'CN':
filename = item[1]
fc = open(root_cert_md5, "a")
fc.write('%s %s\n' % (md5sum, filename))
fc.close()
os.chown(root_cert_md5, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(root_cert_md5, 0644)
if not filename:
print _('Field "CN" not found in the certificate!')
return 1
ca_cert = os.path.join(ca_dir, filename)
fd = open(ca_cert, 'w')
fd.write(ca_root)
fd.close()
os.chown(ca_cert, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(ca_cert, 0644)
user_root_cert = os.path.join(ca_dir, 'ca_root.crt')
fa = open(user_root_cert, 'a')
fa.write(ca_root)
fa.close()
os.chown(user_root_cert, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(user_root_cert, 0644)
# print _("Certificate added")
# else:
# print _("file with the CA certificate now exists")
trust_dir = os.path.join(client_cert_path, 'trusted')
if not os.path.isdir(trust_dir):
os.makedirs(trust_dir)
os.chown(trust_dir, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(trust_dir, 0755)
ca_certs = os.path.join(trust_dir, "cert.list")
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
os.chown(ca_certs, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(ca_certs, 0644)
host = 'localhost'
filename = host
cert_file_trust = os.path.join(trust_dir, filename)
fc = open(cert_file_trust, "w")
fc.write(ca_root)
fc.close()
os.chown(cert_file_trust, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(cert_file_trust, 0644)
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
return 0
# Open file with compliance server certificates and server hostname
fcl = open(ca_certs, "a")
fcl.write(host + ' ' + filename + '\n')
fcl.close()
return 0
def key_force(cert_path, data_path):
while True:
try:
resp = raw_input(_('Do you really want to remove all '
'certificates, requests and config files from '
'the server?') + ' (yes/no): ')
except KeyboardInterrupt:
resp = 'no'
if resp.lower() in ['n', 'no']:
return 0
elif resp.lower() in ['y', 'yes']:
break
if os.path.isdir(cert_path):
shutil.rmtree(cert_path)
remove_dirs = ['conf', 'server_certs', 'client_certs', 'pids', 'sids']
for rm_dir in remove_dirs:
remove_dir = os.path.join(data_path, rm_dir)
if os.path.isdir(remove_dir):
shutil.rmtree(remove_dir)
remove_files = ['sid.db', 'sid_pid']
for rm_file in remove_files:
remove_file = os.path.join(data_path, rm_file)
if os.path.isfile(remove_file):
os.unlink(remove_file)

File diff suppressed because it is too large Load Diff

@ -1,382 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import os
from calculate.lib.utils.tools import unpack_single_opts
import cert_cmd
import pwd
from calculate.core.server.func import clearDataVars
from calculate.lib.cl_lang import setLocalTranslate
import calculate.contrib
# from spyne.protocol.http import HttpRpc
# from spyne.protocol.xml import XmlDocument
# from spyne.protocol.json import JsonDocument
from spyne.protocol.soap import Soap11
from spyne import Application
# from spyne.server.wsgi import WsgiApplication
from spyne_adapter import CoreInnerWsdl, make_service
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
_("User must be root")
_('Failed to import %s')
_('No module named %s')
@clearDataVars
def main(*args, **keywords):
_args = list(unpack_single_opts(sys.argv[1:]))
if os.path.basename(sys.argv[0]) != 'cl-core':
parser = cert_cmd.parse(full=False)
args, unknown_args = parser.parse_known_args(_args)
args.method = '_temp_'
else:
parser = cert_cmd.parse(full=True)
args, unknown_args = parser.parse_known_args(_args)
if args.method:
parser = cert_cmd.parse(full=False)
args, unknown_args = parser.parse_known_args(_args)
if not args.method:
if unknown_args:
args = parser.parse_args(_args)
if args.help and not args.method:
parser.print_help()
return 0
from calculate.core.datavars import DataVarsCore
ob = DataVarsCore()
ob.importCore()
# set var env
if not ob.flIniFile():
sys.exit(1)
# cl_wsdl = ob.Get('cl_wsdl')
cl_wsdl = ob.Get('cl_wsdl_available')
data_path = ob.Get('cl_core_data')
local_data_path = ob.Get('cl_core_local_data')
certbase = ob.Get('cl_core_database')
serv_certbase = ob.Get('cl_core_serv_database')
rights = ob.Get('cl_core_rights')
group_rights = ob.Get('cl_core_group_rights_path')
sids = ob.Get('cl_core_sids_path')
pids = ob.Get('cl_core_pids_path')
sids_pids = ob.Get('cl_core_sids_pids')
sids_file = ob.Get('cl_core_sids_file')
pids_file = ob.Get('cl_core_pids_file')
max_sid = ob.Get('cl_core_max_sid')
max_pid = ob.Get('cl_core_max_pid')
cert_path = ob.Get('cl_core_cert_path')
cert = ob.Get('cl_core_cert')
key = ob.Get('cl_core_key')
cl_ver = ob.Get('cl_ver')
log_path_var = ob.Get('cl_log_path')
cl_core_port = ob.GetInteger('cl_core_port')
port = cl_core_port
file_logger = None
# создать симлинки на команды
if not args.method and args.create_symlink:
from func import create_symlink, initialization
initialization(cl_wsdl)
create_symlink(local_data_path, data_path)
return 0
if args.version:
print cl_ver
return 0
log_filename = None
if ob.Get('cl_ebuild_phase') == '' and os.getuid() == 0:
import logging
import logging.handlers
# logging.raiseExceptions = 0
log_path = args.log_path if args.log_path else log_path_var
if not os.path.exists(log_path):
os.makedirs(log_path)
log_filename = os.path.join(log_path, 'logging_cl_core.out')
file_logger = logging.getLogger('MyLogger')
file_logger.setLevel(logging.DEBUG)
# Add the log message handler to the logger
try:
handler = logging.handlers.RotatingFileHandler(
log_filename, maxBytes=10000000, backupCount=3)
file_logger.addHandler(handler)
# debug
if args.debug:
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('spyne.server.wsgi')
logger.setLevel(logging.DEBUG)
except IOError:
pass
from urllib2 import URLError
from traceback import print_exc
ob.close()
if not args.method:
try:
port = args.port or cl_core_port
if args.check:
import bootstrap
bootstrap.check(cert, key)
return 0
if args.bootstrap_user_name:
import bootstrap
bootstrap.init(cert, key, cert_path, data_path, certbase, args,
port)
if not args.cert_user_name:
return 0
if args.clear_user_cert:
import bootstrap
bootstrap.clear_localuser_certificates(certbase)
if not args.cert_user_name:
return 0
if args.cert_user_name:
cert_user_name = args.cert_user_name
try:
pwd.getpwnam(cert_user_name)
except KeyError:
print _("User %s does not exist") % cert_user_name
return 1
import bootstrap
bootstrap.force_user_cert(cert, cert_path, data_path,
certbase, cert_user_name, dv=ob)
return 0
if args.revoke_cert_id:
cert_cmd.revoke_signed_cert(args.revoke_cert_id, data_path,
cert_path)
return 0
if (args.host or args.gen_root_cert or args.root_host or
args.use_root_cert):
cert_cmd.check_server_certificate(cert, key, cert_path, args,
port)
return 0
if args.id_client_req:
cert_cmd.sing_req_by_server(args.id_client_req, cert_path,
data_path)
return 0
if args.Id:
cert_cmd.view_cert(args, certbase, data_path, rights,
group_rights)
return 0
if args.cert_id:
cert_cmd.view_signed_cert(args, serv_certbase, data_path)
return 0
if args.req_id:
cert_cmd.view_client_request(args, certbase, data_path)
return 0
# Sign request by root certificate
if args.id_server_req:
cert_cmd.sing_req_by_root(args, cert_path, data_path)
return 0
if args.id_del_req or args.id_del_client_req:
cert_cmd.del_request(args.id_del_req, args.id_del_client_req,
serv_certbase, certbase, data_path)
return 0
except BaseException as e:
from urllib2 import URLError
if isinstance(e, URLError) and log_filename:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
print e
else:
raise
params_list = ["start", "create_symlink", "method",
"list_methods"]
for param in params_list:
if hasattr(args, param) and getattr(args, param):
break
else:
parser.print_help()
return 0
#####################
# importing other modules
from func import initialization
outer_wsdl_classes = initialization(cl_wsdl)
pack = "calculate.core.server"
import importlib
func_metaclass = importlib.import_module('%s.func_metaclass' % pack)
core_wsdl_classes = []
core_wsdl_classes.append(func_metaclass.Func_MetaClass)
from calculate.core.server.baseClass import Basic
# make server metaclass
if args.method or args.list_methods:
from local_call import local_method, LocalCall
ClService = CoreInnerWsdl("ClService",
tuple([LocalCall] + outer_wsdl_classes + [Basic] + core_wsdl_classes),
{
"__metaclass__" : CoreInnerWsdl
})
tc = ClService()
tc.set_comb_class_ref(tc)
return local_method(tc, args, unknown_args)
ClService = make_service(Basic, core_wsdl_classes, outer_wsdl_classes, "ClService")
from server_class import ClApplication, OpenSSLAdapter
#do we even need this anymore?
tc = ClService()
App = Application([ClService], 'tns',
name="ClApplication",
in_protocol=Soap11(),
out_protocol=Soap11(),
)
# delete all sid and pid informations file
wsgi_application = ClApplication(App, log=file_logger)
cert_cmd.create_path(data_path, certbase, rights, group_rights,
local_data_path)
# set all path
tc.set_paths(data_path, certbase, serv_certbase,
rights, group_rights, sids, pids, sids_pids,
sids_file, pids_file, max_sid,
max_pid, cert_path, log_filename,
cert, key)
tc.set_comb_class_ref(tc)
tc.run_tasks()
max_num = 99999999
import calculate.contrib
from cherrypy.wsgiserver import CherryPyWSGIServer, WSGIPathInfoDispatcher
dispatcher = WSGIPathInfoDispatcher({'': wsgi_application})
server = CherryPyWSGIServer(('0.0.0.0', port), dispatcher,
numthreads=10, max=max_num,
request_queue_size=max_num)
# logger = logging.getLogger("spyne.application")
# logger.setLevel(0)
print _("listening to https://0.0.0.0:%d") % port
print _("wsdl is located at: https://0.0.0.0:%d/?wsdl") % port
ca_cert = cert_path + "/ca_root.crt"
if not os.path.exists(ca_cert):
ca_cert = None
ssl_adapter = OpenSSLAdapter(cert, key, ca_cert)
ssl_adapter.certbase = certbase
server.ssl_adapter = ssl_adapter
server.certbase = certbase
server.serv_certbase = serv_certbase
server.rights = rights
server.group_rights = group_rights
server.sids = sids
server.pids = pids
server.sids_file = sids_file
server.pids_file = pids_file
server.data_path = data_path
server.cert_path = cert_path
server.ssl_certificate = cert
server.ssl_private_key = key
from OpenSSL.SSL import Error as SSLError
import socket
try:
if args.pidfile:
try:
with open(args.pidfile, "w") as f:
f.write(str(os.getpid()))
except OSError:
sys.stderr.write(_("failed to create PID file %s")
% args.pidfile + "\n")
sys.exit(1)
# For cleaning of sessions at server reboot
from clean import clean
from gen_pid import clear_finished_pids
from calculate.lib.utils.files import writeFile
clean(sids_file, pids_file, sids_pids, sids, pids)
clear_finished_pids(ob)
print _("Server started")
dbus_stop_file = ob.Get('cl_core_dbus_stop_path')
if args.inactiveclose:
try:
writeFile(dbus_stop_file).close()
except (OSError, IOError):
pass
else:
if os.path.exists(dbus_stop_file):
os.unlink(dbus_stop_file)
server.start()
except KeyboardInterrupt:
try:
ClService.killall()
except KeyboardInterrupt:
pass
print '\n' + _("Server stopped")
server.stop()
sys.exit(0)
except socket.error, e:
if e.message == "No socket could be created":
print _("No socket could be created")
print _('Port %d already in use') % port
else:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
print e
except SSLError:
print '\n', _('Server certificate not found') # , e
print _("use cl-core with option --gen-cert-by HOST "
"(--get-cert-from HOST) or --use-root-as-server)")
except Exception:
if file_logger:
fd = open(log_filename, 'a')
file_logger.debug(print_exc(file=fd))
fd.close()
server.stop()
if args.pidfile:
if os.path.exists(args.pidfile):
os.unlink(args.pidfile)
sys.exit(0)

@ -1,190 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import glob
import sys
import time
import datetime
import pickle
from calculate.core.datavars import DataVarsCore
from calculate.core.server.core_interfaces import CoreServiceInterface
from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
def clean(sid_file, pid_file, sid_pid, sids_dir, pids_dir):
"""
Удалить все файлы сервера после перезапуска
"""
for fn in (sid_file, pid_file, sid_pid):
if os.path.exists(fn):
try:
os.unlink(fn)
except OSError:
pass
for dn in (sids_dir, pids_dir):
if os.path.isdir(dn):
for filename in glob.glob(os.path.join(dn, "*.sid")):
try:
os.unlink(filename)
except OSError:
pass
class CoreWsdl(CoreServiceInterface):
# watch for process
@staticmethod
def watcher_pid_proc(cls, sid, pid):
period = 2
time.sleep(period)
try:
# while process status "Active"
while cls.glob_process_dict[pid]['status'] == 1:
# frequency check
time.sleep(period)
cls.delete_pid(cls, sid, pid)
except IOError as e:
print 'Except IOError', str(e)
except Exception:
print _("PID %d watcher error") % pid
try:
cls.delete_pid(cls, sid, pid)
except Exception:
pass
time.sleep(0.1)
@staticmethod
def delete_pid(cls, sid, pid):
while len(cls.glob_frame_list[pid]) > \
cls.glob_process_dict[pid]['counter']:
time.sleep(1)
methodname = cls.glob_process_dict[pid]['method_name']
if methodname:
cls.clear_cache(sid, methodname)
cls.del_pid(cls, pid)
cls.del_pid_from_sid_pid(cls, pid)
def monitor(certbase, sid_file):
""" function to delete old session """
# Get value of period and lifetime session from DataVars
try:
ob = DataVarsCore()
ob.importCore()
if not ob.flIniFile():
sys.exit(1)
period = float(ob.Get('cl_core_monitor_period'))
sid_live = float(ob.Get('cl_core_sid_live'))
except Exception:
print _("Variable cl_core_monitor_period or cl_core_sid_live not "
"found")
raise
# Check lifetime. if necessary, remove
while True:
# check session
try:
sid_file_t = sid_file + '_temp'
fd = open(sid_file, 'r')
ft = open(sid_file_t, 'w')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
break
# how time exists session
delta = datetime.datetime.now() - list_sid[2]
# if not outdated, then leave
if delta.seconds < sid_live * 60:
pickle.dump(list_sid, ft)
fd.close()
ft.close()
# copy all from temp file
ft = open(sid_file_t, 'rb')
fd = open(sid_file, 'wb')
ft.seek(0)
fd.write(ft.read())
ft.close()
fd.close()
# Delete temp file
os.unlink(sid_file_t)
except (IOError, OSError):
return 1
# Частота проверки
time.sleep(60 * period)
# check client's presence
def sid_monitor(sid_fn, sids_dn, cls):
# check interval
period = 21
while True:
try:
sids = []
# create, if file not exists
if not os.path.exists(sid_fn):
temp = open(sid_fn, 'w')
temp.close()
fd = open(sid_fn, 'r')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
break
# add session id in sesession list
sids.append(list_sid[0])
fd.close()
except (IOError, OSError):
print _("Error reading SID files")
return
try:
# for each session
for filename in sids:
# find file this session
sid_path = sids_dn + "/%d.sid" % filename
with cls.sid_locker:
if os.path.isfile(sid_path):
with open(sid_path) as fd:
# read information about session
sid_inf = pickle.load(fd)
# if number of missed inspections more 3
if sid_inf[1] > 3:
# flag client absence
sid_inf[2] = 1
fd.close()
if os.path.isfile(sid_path):
# add to digit missed inspections
# client constantly nulls this value!
ft = open(sid_path, 'w')
if sid_inf[1] < 4:
sid_inf[1] += 1
pickle.dump(sid_inf, ft)
ft.close()
except (IOError, OSError, KeyError):
pass
# check period
time.sleep(period)

@ -1,247 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import urllib2 as u2
import os
import sys
import calculate.contrib
from suds.transport.http import HttpTransport
from httplib import HTTPConnection, HTTPSConnection
import socket
from calculate.core.datavars import DataVarsCore
from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
class clientHTTPSConnection(HTTPSConnection):
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None, cert_path=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
self.cert_path = cert_path
# get filename store cert server
def cert_list(self, host, ca_certs, server_cert):
if not os.path.exists(self.ca_path):
try:
os.makedirs(self.ca_path)
except OSError:
pass
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
filename = None
try:
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == host:
filename = words[1]
if not filename:
return None
except (IOError, IndexError):
print _("Certificate not found on the client's side")
return None
try:
fd = open(self.ca_path + filename, 'r')
store_cert = fd.read()
fd.close()
if store_cert == server_cert:
return filename
except IOError as e:
print _("Failed to open the file") + "%s%s %s" % (self.ca_path,
filename, str(e))
return None
# add certificate server in trusted
def add_server_cert(self, cert):
print _("Untrusted server certificate!")
import OpenSSL
certobj = OpenSSL.crypto.load_certificate(OpenSSL.SSL.FILETYPE_PEM,
cert)
print '\n' + _("Fingerprint = %s") % certobj.digest('SHA1')
print _("Serial number = "), certobj.get_serial_number()
Issuer = certobj.get_issuer().get_components()
print '\n' + _("Issuer")
for i in Issuer:
print "%s : %s" % (i[0], i[1])
Subject = certobj.get_subject().get_components()
print '\n' + _("Subject")
for item in Subject:
print "%s : %s" % (item[0], item[1])
choice = raw_input(
_("add this certificate to trusted and continue? y/[n]: "))
if choice in ['y', 'yes', 'Y', 'YES']:
ca_certs = self.ca_path + "cert.list"
if not os.path.exists(ca_certs):
fc = open(ca_certs, "w")
fc.close()
filename = self.host
fc = open(self.ca_path + filename, "w")
fc.write(cert)
fc.close()
with open(ca_certs) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
# Split string into a words list
words = line.split()
if len(words) > 1:
# if first word...
if words[0] == self.host:
return 0
# Open file with compliance server certificates and server hostname
fcl = open(ca_certs, "a")
fcl.write(self.host + ' ' + filename + '\n')
fcl.close()
else:
sys.exit()
def connect_trusted_server(self, sock):
import ssl
if hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
else:
print _("SSL library is not support TLSv1_2")
return 1
self.ca_path = self.cert_path + "ca/"
ca_certs = self.ca_path + "cert.list"
server_cert = ssl.get_server_certificate(addr=(self.host, self.port))
if (not hasattr(HTTPSClientsCertTransport, 'filename') or
HTTPSClientsCertTransport.filename is None):
HTTPSClientsCertTransport.filename = self.cert_list(
self.host, ca_certs, server_cert)
if HTTPSClientsCertTransport.filename:
try:
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_NONE)
dercert_after_connect = self.sock.getpeercert(True)
cert_after_connect = ssl.DER_cert_to_PEM_cert(
dercert_after_connect)
filename2 = self.cert_list(self.host, ca_certs,
cert_after_connect)
if not HTTPSClientsCertTransport.filename == filename2:
print '\n' + _("WARNING!!! %s trying to replace the "
"certificate!") % self.host + '\n'
self.sock.close()
return 2
return 0
except Exception:
print _("Error. The server certificate and the private "
"key are probably invalid!")
HTTPSClientsCertTransport.filename = None
return 1
else:
self.sock = ssl.wrap_socket(sock)
self.add_server_cert(server_cert)
def connect(self):
"""Connect to a host on a given (SSL) port."""
timeout = 15
sock = socket.create_connection((self.host, self.port),
timeout, self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
clVars = DataVarsCore()
clVars.importCore()
if not clVars.flIniFile():
sys.exit(1)
import ssl
if hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
else:
print _("SSL library is not support TLSv1_2")
sys.exit(1)
self.sock = ssl.wrap_socket(sock,
certfile=self.cert_file,
keyfile=self.key_file,
ssl_version=ssl_version,
cert_reqs=ssl.CERT_NONE)
class HTTPSClientAuthHandler(u2.HTTPSHandler):
def __init__(self, key, cert, cert_path):
u2.HTTPSHandler.__init__(self)
self.key = key
self.cert = cert
self.cert_path = cert_path
def https_open(self, req):
# Rather than pass in a reference to a connection class, we pass in
# a reference to a function which, for all intents and purposes,
# will behave as a constructor
return self.do_open(self.getConnection, req)
def getConnection(self, host, timeout=300):
return clientHTTPSConnection(host, key_file=self.key,
cert_file=self.cert,
cert_path=self.cert_path)
class HTTPSClientsCertTransport(HttpTransport):
def __init__(self, key, cert, path_to_cert, *args, **kwargs):
HttpTransport.__init__(self, *args, **kwargs)
self.key = key
self.cert = cert
self.cert_path = path_to_cert
def u2open(self, u2request):
"""
Open a connection.
@param u2request: A urllib2 request.
@type u2request: urllib2.Requet.
@return: The opened file-like urllib2 object.
@rtype: fp
"""
tm = self.options.timeout
url = u2.build_opener(HTTPSClientAuthHandler(self.key, self.cert,
self.cert_path))
# from urllib2 import URLError
# try:
if hasattr(self, "u2ver"):
if self.u2ver() < 2.6:
socket.setdefaulttimeout(tm)
return url.open(u2request)
else:
return url.open(u2request, timeout=tm)
else:
return url.open(u2request, timeout=tm)

@ -1,189 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from M2Crypto import RSA, X509, EVP, m2
from calculate.lib.cl_lang import setLocalTranslate
from binascii import hexlify
import hashlib
from calculate.lib.utils.text import _u8
from M2Crypto import m2
from M2Crypto.X509 import X509_Extension
from calculate.lib.utils.files import writeFile, readFile
from ctypes import *
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
def passphrase_callback(v):
return ""
def generateRSAKey():
return RSA.gen_key(2048, m2.RSA_F4)
def makePKey(key):
pkey = EVP.PKey()
pkey.assign_rsa(key)
return pkey
def makeRequest(pubkey, pkey, serv_host, port):
""" create query to the signing on server """
req = X509.Request()
# Seems to default to 0, but we can now set it as well, so just API test
req.set_version(req.get_version())
req.set_pubkey(pkey)
name = X509.X509_Name()
c = raw_input(_("Enter the certificate date manually? [y]/n: "))
if c.lower() in ['n', 'no']:
name.CN = 'root_cert' # (Common Name);
name.OU = 'www.calculate-linux.ru' # (Organization Unit);
name.O = 'calculate-linux' # (Organization Name);
name.L = '' # (Locality Name);
name.ST = 'Spb' # (State Name);
name.C = 'En' # (Country);
else:
import socket
print _('Do not use spaces or tabs.')
host_name = socket.getfqdn()
# if serv_host == host_name:
# print '\n'+_("Want to create self-signed certificate?\n"
# "Use key --gen-cert-self")
# return None
if serv_host in host_name:
host_name = host_name.replace('.' + serv_host, '')
list_host_name = host_name.split('.')
print 'list_host_name = ', list_host_name
result_host_name = \
list_host_name[len(list_host_name) - 1] + "." + serv_host
else:
host_name = socket.getfqdn()
list_host_name = host_name.split('.')
result_host_name = list_host_name[0] + "." + serv_host
def cleardata(x):
if x:
return x.replace(' ', '_').replace('\t', '_')
return ""
_CN = raw_input(_('Hostname [%s] : ') % _u8(result_host_name))
name.CN = _CN or result_host_name or ""
_OU = raw_input(_('Organization unit: '))
name.OU = cleardata(_OU)
_O = raw_input(_('Organization name: '))
name.O = cleardata(_O)
network = _('Full network address (host:port)')
_L = raw_input(network + ' [%s:%d]: ' % (_u8(host_name), port))
name.L = cleardata(_L) or (_u8(host_name) + ':' + str(port))
_ST = raw_input(_('City: '))
name.ST = cleardata(_ST)
_C = raw_input(_('Country (two letters only!): '))
name.C = _C or "C"
req.set_subject_name(name)
ext1 = X509.new_extension('nsComment', 'Auto Generated')
extstack = X509.X509_Extension_Stack()
extstack.push(ext1)
req.add_extensions(extstack)
req.sign(pkey, 'md5')
return req
class CreateCertError(Exception):
pass
def create_selfsigned_ca(dn_data, keyfile, certfile):
from OpenSSL import crypto
certpem = readFile(keyfile)
if not certpem:
raise CreateCertError(_("Key file {} not found").format(keyfile))
try:
pkey = crypto.load_privatekey(
crypto.FILETYPE_PEM, certpem)
ca = crypto.X509()
ca.set_version(2)
subject = ca.get_subject()
subject.countryName = dn_data['C']
subject.commonName = dn_data['CN']
subject.stateOrProvinceName = dn_data['ST']
subject.localityName = dn_data['L']
subject.organizationName = dn_data['O']
subject.organizationalUnitName = dn_data['OU']
ca.gmtime_adj_notBefore(-60*60*24)
ca.gmtime_adj_notAfter(60*60*24*365*20)
ca.set_issuer(subject)
ca.set_pubkey(pkey)
ca.add_extensions([
crypto.X509Extension(b'basicConstraints', True, b'CA:TRUE'),
#crypto.X509Extension(b'keyUsage', False, b'keyCertSign, cRLSign'),
crypto.X509Extension(b'subjectKeyIdentifier', False, b'hash', subject=ca)])
ca.add_extensions([crypto.X509Extension(b'authorityKeyIdentifier', False, b'keyid:always',issuer=ca)])
ca.sign(pkey, 'sha1')
with writeFile(certfile) as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, ca))
except crypto.Error as e:
raise CreateCertError(str(e))
def sign_client_certifacation_request(ca_keyfile, ca_certfile, requestfile, out_cert, group):
from OpenSSL import crypto
cakeyfilepem = readFile(ca_keyfile)
cacertpem = readFile(ca_certfile)
requestpem = readFile(requestfile)
if not cakeyfilepem:
raise CreateCertError(
_("Key file {} not found").format(ca_keyfile))
if not cacertpem:
raise CreateCertError(
_("CA certitficate file {} not found").format(ca_certfile))
if not requestpem:
raise CreateCertError(
_("Request file {} not found").format(requestfile))
try:
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, cakeyfilepem)
ca = crypto.load_certificate(crypto.FILETYPE_PEM, cacertpem)
req = crypto.load_certificate_request(crypto.FILETYPE_PEM, requestpem)
cert = crypto.X509()
cert.set_version(2)
cert.gmtime_adj_notBefore(-60*60*24)
cert.gmtime_adj_notAfter(60*60*24*365*20)
cert.set_issuer(ca.get_subject())
cert.set_subject(req.get_subject())
cert.set_pubkey(req.get_pubkey())
cert.add_extensions([
crypto.X509Extension(b'basicConstraints', False, b'CA:FALSE'),
crypto.X509Extension(b'nsCertType', False, b'client'),
crypto.X509Extension(b'keyUsage', False, b'digitalSignature, keyEncipherment'),
crypto.X509Extension(b'extendedKeyUsage', False, b'clientAuth'),
crypto.X509Extension(b'nsComment', False, 'group:{}'.format(group)),
])
cert.sign(pkey, 'sha1')
with writeFile(out_cert) as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
except crypto.Error as e:
raise CreateCertError(str(e))

File diff suppressed because it is too large Load Diff

@ -1,278 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import pickle
import threading
from os import path
import random
from calculate.core.server.core_interfaces import CoreServiceInterface
from calculate.lib.utils.files import listDirectory, readFile, readLinesFile
from calculate.lib.utils.tools import ignore
import socket
from cert_cmd import find_cert_id
class ProcessStatus(object):
SuccessFinished = 0
Worked = 1
FailedFinished = 2
NotFound = 3
Paused = 4
class ProcessMode(object):
CoreDaemon = "core"
LocalCall = "local"
def get_symlink_commands():
"""
Получить список команд утилит
"""
symlinks = "/var/lib/calculate/calculate-core/conf/symlinks"
for line in readLinesFile(symlinks):
yield line.strip()
yield "/usr/bin/cl-core"
yield "/usr/bin/cl-update"
yield "/usr/bin/cl-core-patch"
def search_worked_process(method_name, clVars,
statuses=(ProcessStatus.Worked,)):
"""
Найти все работающие процессы
Возвращает список процессов со статусом Worked и существующем системным
процессом
"""
def generator():
pids = clVars.Get('core.cl_core_pids_path')
for pidfile in listDirectory(pids, fullPath=True):
try:
status = pickle.load(open(pidfile))
if ((method_name is None or status['name'] == method_name) and
status['status'] in statuses):
pid_path = path.join("/proc", str(status['os_pid']))
if path.exists(pid_path):
cmdline = readFile(path.join(pid_path, "cmdline"))
if cmdline and any(x in cmdline
for x in get_symlink_commands()):
yield status['os_pid']
except (socket.error, ValueError, KeyError, EOFError, OSError):
pass
return list(generator())
worked_filter = lambda x: x['status'] == ProcessStatus.Worked
def search_worked_process2(clVars, filter_func=lambda x: True,
status_filter=worked_filter):
pids = clVars.Get('core.cl_core_pids_path')
for pidfile in listDirectory(pids, fullPath=True):
try:
status = pickle.load(open(pidfile))
if status_filter(status) and filter_func(status):
pid_path = path.join("/proc", str(status['os_pid']))
if path.exists(pid_path):
cmdline = readFile(path.join(pid_path, "cmdline"))
if cmdline and any(x in cmdline
for x in get_symlink_commands()):
yield status['os_pid']
except (socket.error, ValueError, KeyError, EOFError, OSError):
pass
def get_pid_info(clVars, statuses=(ProcessStatus.Worked,)):
"""
Получить информацию о процессах
"""
def generator():
pids = clVars.Get('core.cl_core_pids_path')
for pidfile in listDirectory(pids, fullPath=True):
try:
status = pickle.load(open(pidfile))
if status['status'] in statuses:
if path.exists(path.join("/proc", str(status['os_pid']))):
yield status
except (socket.error, ValueError, KeyError, EOFError, OSError):
pass
return list(generator())
# try:
# pidfile = path.join(pids,str(pid))
# status = pickle.load(open(pidfile))
# return status
# except (socket.error, ValueError, IOError, KeyError, EOFError, OSError):
# return None
def clear_finished_pids(clVars):
"""
Удалить все идентификационные файлы завершившихся процессов
"""
pids = clVars.Get('core.cl_core_pids_path')
for pidfile in listDirectory(pids, fullPath=True):
try:
d = pickle.load(open(pidfile))
if path.exists(path.join("/proc", str(d['os_pid']))):
continue
except Exception:
pass
with ignore(OSError):
os.unlink(pidfile)
# process management
class CoreWsdl(CoreServiceInterface):
#for debugging:
gen_pid_testing_val = "Gen pid represents"
# delete process id from list process
@staticmethod
def del_pid(cls, pid):
try:
rst = []
pid_str = str(pid)
# open the file list of process
with open(cls.pids_file) as fd:
t = fd.read()
for line in t.splitlines():
# Leave all but removed
if line != pid_str:
rst.append(line)
# write all in file
fd = open(cls.pids_file, 'w')
fd.write('\n'.join(rst))
fd.write('\n') # with join we lose the last newline char
fd.close()
cls.glob_process_dict.pop(pid)
cls.glob_progress_dict.pop(pid)
cls.glob_table_dict.pop(pid)
cls.glob_frame_list.pop(pid)
with ignore(OSError):
rm_fn = path.join(cls.pids, "%d.pid" % pid)
if path.exists(rm_fn):
os.unlink(rm_fn)
return 0
except Exception:
return 1
# find process id in file processes, 1 - yes, 0 - none
@staticmethod
def find_pid_in_file(cls, find_pid):
temp_line = ''
# create, if file not exists
if not os.path.exists(cls.pids_file):
temp = open(cls.pids_file, 'w')
temp.close()
with open(cls.pids_file) as fd:
t = fd.read()
# for each line
for line in t.splitlines():
try:
temp_line = int(line)
except ValueError:
pass
# if process id found
if temp_line == find_pid:
return 1
fd.close()
return 0
# add process id in file
@staticmethod
def add_pid_in_file(cls, pid):
pid_t = str(pid)
fd = open(cls.pids_file, 'a')
fd.write(pid_t)
fd.write('\n')
fd.close()
return 0
# issue new pid for created process
@staticmethod
def gen_pid(cls):
while True:
new_pid = random.randint(1, cls.max_pid)
# flag = 1 - exists, 0 - missing in PID_FILE
if cls.find_pid_in_file(cls, new_pid) == 0:
cls.add_pid_in_file(cls, new_pid)
return new_pid
@staticmethod
def check_sid_cert(cls, sid):
curThread = threading.currentThread()
certificate = curThread.client_cert
cert_id = find_cert_id(certificate, cls.data_path, cls.certbase)
# if certificate not found in database
if cert_id == 0:
return -1
# check, This certificate is launched session
# Data taken from sid.db
flag = 0
# create, if file not exists
if not os.path.exists(cls.sids_file):
return 0
# temp = open(cls.sids_file, 'w')
# temp.close()
fd = open(cls.sids_file, 'r')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
break
# when session id equal readable...
if int(sid) == int(list_sid[0]):
# ... and certificate id equal launched this session...
if int(cert_id) == int(list_sid[1]):
# ... set flag
flag = 1
fd.close()
# if validation fails
return flag
@staticmethod
def serv_pid_kill(cls, pid, sid):
""" Set flag to complete the process """
check_sid = cls.check_sid_cert(cls, sid)
if not check_sid:
return -2
# write complete flag (pid_list[6] = 1) in process file
if not os.path.exists(cls.pids):
os.mkdir(cls.pids)
if pid not in cls.process_pid:
return 3
meth = cls.process_pid[pid]
if meth.is_alive():
try:
os.kill(meth.pid, 2)
except OSError, e:
print 'No such process %d' % meth.pid, e
return 1
return 0

@ -1,259 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Session management
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import datetime
import threading
import random
import pickle
from calculate.core.server.core_interfaces import CoreServiceInterface
from cert_cmd import find_cert_id
class CoreWsdl(CoreServiceInterface):
sid_locker = threading.Lock()
# delete client session from file (close session)
@staticmethod
def del_sid_from_file(cls, sid):
try:
# temp file
sid_file = cls.sids_file
sid_file_t = sid_file + 'temp'
with cls.sid_locker:
fd = open(sid_file, 'r')
ft = open(sid_file_t, 'w')
while True:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, IOError, KeyError):
break
# Leave all but removed
if sid != list_sid[0]:
pickle.dump(list_sid, ft)
fd.close()
ft.close()
# copy all from temp file
ft = open(sid_file_t, 'rb')
fd = open(sid_file, 'wb')
ft.seek(0)
fd.write(ft.read())
ft.close()
fd.close()
# delete temp file
os.unlink(sid_file_t)
return ['0']
except (IOError, EOFError, KeyError, OSError):
return ['1']
# find session id in file
@staticmethod
def find_sid_in_file(cls, sid):
sid_file = cls.sids_file
# create, if file not exists
with cls.sid_locker:
if not os.path.exists(sid_file):
temp = open(sid_file, 'w')
temp.close()
fd = open(sid_file, 'r')
while True:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, IOError, KeyError):
break
# if session id found
if sid == list_sid[0]:
fd.close()
return 1
fd.close()
return 0
# add session id in file
@staticmethod
def add_sid_in_file(cls, sid, cert_id, lang):
# list Format (session number, cert number, time start session)
list_sid = [sid, cert_id, datetime.datetime.now()]
# session's file
if not os.path.exists(cls.sids):
os.mkdir(cls.sids)
sids_dir = cls.sids
sid_file = sids_dir + "/%d.sid" % sid
# create session's file
with cls.sid_locker:
fp = open(sid_file, 'w')
sid_list = [sid, 0, 0, lang]
pickle.dump(sid_list, fp)
fp.close()
# add session in list sessions
fd = open(cls.sids_file, 'a')
pickle.dump(list_sid, fd)
fd.close()
return 0
@staticmethod
def set_sid_lang(cls, sid, lang):
sids_dir = cls.sids
sid_file = os.path.join(sids_dir, "%d.sid" % sid)
with cls.sid_locker:
if not os.path.isfile(sid_file):
fp = open(sid_file, 'w')
fp.close()
fd = open(sid_file, 'r')
try:
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
list_sid = [sid, 0, 0, lang]
fd.close()
fp = open(sid_file, 'w')
list_sid[3] = lang
pickle.dump(list_sid, fp)
fp.close()
# issue number of new session (and registered its)
@staticmethod
def sid_cmp(cls, sid, cert_id, lang):
if sid < 0 or sid > cls.max_sid:
sid = 0
session = 1
# if session is new
if sid == 0:
while True:
new_sid = random.randint(1, cls.max_sid)
# flag = 1 - exists, 0 - missing in SID_FILE
if cls.find_sid_in_file(cls, new_sid) == 0:
cls.add_sid_in_file(cls, new_sid, cert_id, lang)
sid = new_sid
break
# if session is old
else:
# find number in file registered
# if not registered
if not cls.find_sid_in_file(cls, sid):
# add session id in file
cls.add_sid_in_file(cls, sid, cert_id, lang)
else:
cls.set_sid_lang(cls, sid, lang)
# set - old session
session = 0
# session id and flag (new or old) session
return [sid, session]
@staticmethod
def serv_init_session(cls, sid, lang):
day_cert = 600
cur_thread = threading.currentThread()
certificate = cur_thread.client_cert
if certificate is None:
return [-3], [0]
checked_id = find_cert_id(certificate, cls.data_path, cls.certbase)
try:
if int(checked_id) < 1:
return [-4], [0]
except ValueError:
return [-4], [0]
results = []
cert_id = checked_id
with open(cls.certbase) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
# and each word in line
words = line.split()
# if in line present certificate id
if len(words) > 3:
if words[0] == checked_id:
results.append(checked_id)
date = datetime.datetime.strptime(
words[2] + ' ' + words[3], '%Y-%m-%d %H:%M:%S.%f')
d = datetime.datetime.now() - date
v = day_cert - d.days # How many days left certificate
if v < 0:
# Method deleted certificate
v = -2 # expiry date has passed
elif v > 60: # For a long time, is not displayed to
# the client
v = -1
results.append(v)
# return results
if not results:
return [-4], [0]
return results, cls.sid_cmp(cls, sid, cert_id, lang)
@staticmethod
def serv_sid_info(cls, sid):
""" Get information about sid """
cert_id = 0
results = []
sid_file = cls.sids_file
with cls.sid_locker:
fd = open(sid_file, 'r')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (IOError, KeyError, EOFError):
break
# if sid found
if sid == list_sid[0]:
cert_id = list_sid[1]
fd.close()
# Get information about sid
if cert_id == 0:
return ["-1"]
with cls.sid_locker:
with open(cls.certbase) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
# and each word in line
words = line.split()
# if in line present certificate id
if words[0] == str(cert_id):
# certificate id
results.append(words[0])
# Date issue certificate
results.append(words[2] + ' ' + words[3])
# ip
results.append(words[4])
# mac
results.append(words[5])
# client type
results.append(words[6])
if not os.path.exists(cls.sids):
os.makedirs(cls.sids)
sid_path = cls.sids + "/%d.sid" % sid
with open(sid_path) as fs:
# read info about session
sid_inf = pickle.load(fs)
# flag absence client
results.append(str(sid_inf[2]))
return results
return ["-2"]

@ -1,677 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pickle
import sys
import termios
import os
from os import path
from fcntl import ioctl
from array import array
import threading
import argparse
import re
from calculate.lib.utils.colortext import get_terminal_print
from calculate.lib.utils.colortext.palette import TextState
from calculate.lib.utils.text import tableReport
from calculate.lib.cl_print import color_print
from calculate.lib.datavars import VariableError, CriticalError
from calculate.lib.cl_lang import setLocalTranslate
from calculate.core.server.api_types import FieldAdapter
from calculate.lib.utils.tools import ignore
from calculate.lib.utils.files import makeDirectory
from calculate.core.result_viewer import ResultViewer
from calculate.core.server.loaded_methods import LoadedMethods
from calculate.core.result_viewer_gui import ProgressGui, ErrorGui, WarningGui
from gen_pid import ProcessStatus
from methods_func import (get_method_argparser, collect_object,
check_result_msg, get_param_pwd, _print,
display_error)
from api_types import ViewInfo, ViewParams
from cert_cmd import parse
from methods_func import GotErrorField
from func import shortTraceback, CommonMethods, CommonLink
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
from itertools import izip, ifilter
class LocalCall(object):
method_status = ProcessStatus.NotFound
no_progress = None
gui_progress = None
gui_warning = None
no_questions = None
@staticmethod
def startprocess(cls, sid, target=None, method=None, method_name=None,
auto_delete=False, args_proc=()):
""" start process """
if "LANG" in os.environ:
curThread = threading.currentThread()
curThread.lang = os.environ["LANG"]
com = target(cls.no_progress, cls.gui_progress, cls.gui_warning,
cls.no_questions)
if len(com.__class__.__bases__) > 1 and \
hasattr(com.__class__.__bases__[1], '__init__'):
com.__class__.__bases__[1].__init__(com)
com.method_name = method_name
com.method_status = ProcessStatus.Worked
if getattr(com, method)(*args_proc):
cls.method_status = ProcessStatus.SuccessFinished
else:
cls.method_status = ProcessStatus.FailedFinished
com.method_status = cls.method_status
cls.del_pid_file(cls, os.getpid(), com.clVars)
return 0
@staticmethod
def del_pid_file(cls, pid, clVars=None):
if clVars:
pids = clVars.Get('core.cl_core_pids_path')
else:
pids = '/tmp'
pid_file = path.join(pids, '%d.pid' % pid)
with ignore(OSError):
if path.exists(pid_file):
os.unlink(pid_file)
class Common(CommonMethods, CommonLink):
""" class to interact with the processes """
def __init__(self, no_progress, gui_progress, gui_warning,
no_questions):
self.pid = 0
self.method_name = ""
self.method_status = ProcessStatus.Worked
self.color_print = color_print()
self.result_viewer = ResultViewer()
if no_questions:
self.result_viewer.set_no_questions()
if no_progress:
self.result_viewer.set_no_progress()
if gui_progress:
self.result_viewer = ErrorGui(ProgressGui(self.result_viewer))
if gui_warning:
self.result_viewer = WarningGui(self.result_viewer)
self.set_link(self.result_viewer)
def pauseProcess(self):
self.method_status = ProcessStatus.Paused
self.writeFile()
def resumeProcess(self):
self.method_status = ProcessStatus.Worked
self.writeFile()
def writeFile(self):
""" write data in file """
from calculate.core.server.gen_pid import ProcessMode
if os.getuid():
return
pid = os.getpid()
pids = self.clVars.Get('core.cl_core_pids_path')
# пропустить создание файла если идет сборка пакета
if self.clVars.Get('cl_ebuild_phase'):
return
if self.clVars.Get('cl_root_readonly') == 'on':
return
build_id = ""
try:
from calculate.builder.variables.action import Actions
if self.clVars.Get('cl_action') in Actions.All:
build_id = self.clVars.Get('builder.cl_builder_id')
except Exception:
pass
if not os.path.exists(pids):
makeDirectory(pids)
pid_file = path.join(pids, '%d.pid' % pid)
try:
with open(pid_file, 'w') as f:
d = {'name': self.method_name,
'mode': ProcessMode.LocalCall,
'os_pid': pid,
'status': self.method_status,
'id': build_id}
pickle.dump(d, f)
except (IOError, OSError) as e:
print str(e)
print _("Failed to write the PID file %s!") % pid_file
def isInteractive(self):
"""
Check interactive ability
"""
return sys.stdin.isatty()
def cout_progress(string=None):
try:
h, w = array('h', ioctl(sys.stderr, termios.TIOCGWINSZ, '\0' * 8))[:2]
except IOError:
return
sys.stdout.write('\r' + (' ' * w))
if string:
sys.stdout.write('\r' + string)
else:
sys.stdout.write('\r')
sys.stdout.flush()
def local_method(metaObject, args, unknown_args):
"""
Call method from metaclass, check method existing.
Generate help, for method, run method by 'call_method'.
"""
import os
sym_link = os.path.basename(sys.argv[0])
if sym_link != 'cl-core':
if sym_link in LoadedMethods.conMethods.keys():
args.method = LoadedMethods.conMethods[sym_link][0]
else:
_print(_("Method not found for %s") % sym_link)
sys.exit(1)
if args.list_methods:
for k, v in sorted(LoadedMethods.conMethods.items(),
key=lambda x: x[1]):
name, user, title = v
print "%s - %s" % (name, title)
return 0
colorPrint = color_print()
# metaObject = metaclass()
method_name = args.method
method_view_name = method_name + '_view'
if args.method and args.help:
force_param = args.no_questions or has_force_arg(unknown_args)
while True:
view_obj = ViewParams()
view_obj.step = None
view_obj.expert = True
view_obj.brief = None
view_obj.onlyhelp = True
view_obj.help_set = True
view_obj.conargs = [x[0] for x in args._get_kwargs() if x[1] is not None]
view_obj.dispatch_usenew = \
force_param
try:
view = getattr(metaObject, method_view_name)(metaObject, 0, view_obj)
except AttributeError:
colorPrint.printERROR(_('Method not found: ') + method_view_name)
return 1
try:
method_parser = get_method_argparser(view, args, cl_core=True)
except Exception:
# import traceback
# for i in apply(traceback.format_exception, sys.exc_info()):
# sys.stderr.write(i)
# sys.stderr.flush()
metaObject.clear_cache(0, method_name)
return 1
_unknown_args = method_parser.fixBoolVariables(unknown_args)
_args, _unknown_args = method_parser.parse_known_args(_unknown_args)
if (view_obj.dispatch_usenew == _args.no_questions
or args.no_questions):
method_parser.print_help()
break
else:
force_param = _args.no_questions
metaObject.clear_cache(0, method_name)
else:
try:
call_method(metaObject, args, unknown_args, colorPrint)
metaObject.clear_cache(0, method_name)
return metaObject.method_status
except (VariableError) as e:
colorPrint.printERROR(str(e))
# colorPrint.printERROR(shortTraceback(*sys.exc_info()))
except (ValueError, CriticalError) as e:
colorPrint.printERROR(str(e))
# colorPrint.printERROR(shortTraceback(*sys.exc_info()))
except (KeyboardInterrupt, EOFError):
colorPrint.printERROR(_('Manually interrupted'))
except (GotErrorField,):
pass
except Exception:
colorPrint.printERROR(shortTraceback(*sys.exc_info()))
pass
# print 'Error: ', e
metaObject.clear_cache(0, method_name)
def call_method(metaObject, args, unknown_args, colorPrint):
"""
Function for call method through metaObject and args
"""
method_name = args.method
stdin_passwd = args.stdin_passwd
method_view_name = method_name + '_view'
metaObject.no_progress = args.no_progress
metaObject.gui_progress = args.gui_progress
metaObject.gui_warning = args.gui_warning
metaObject.no_questions = False
view = None
method_parser = None
dispatch_usenew = args.no_questions or has_force_arg(unknown_args)
while True:
view_obj = ViewInfo()
view_obj.step = None
view_obj.expert = True
view_obj.brief = None
view_obj.onlyhelp = True
view_obj.help_set = False
view_obj.conargs = [x for x in unknown_args]
view_obj.dispatch_usenew = dispatch_usenew
try:
view = getattr(metaObject, method_view_name)(metaObject, 0, view_obj)
except AttributeError:
colorPrint.printERROR(_('Method not found: ') + method_name)
return None
method_parser = get_method_argparser(view, args, cl_core=True)
_unknown_args = method_parser.fixBoolVariables(unknown_args)
_args, _unknown_args = method_parser.parse_known_args(_unknown_args)
if (view_obj.dispatch_usenew == _args.no_questions or
args.no_questions):
break
else:
dispatch_usenew = _args.no_questions
metaObject.clear_cache(0, method_name)
no_questions = dispatch_usenew
param_object = create_param_object(view)
try:
unknown_args = method_parser.fixBoolVariables(unknown_args)
args, unknown_args = method_parser.parse_known_args(unknown_args)
metaObject.no_questions = no_questions
except SystemExit:
return 1
except Exception:
import traceback
for i in apply(traceback.format_exception, sys.exc_info()):
sys.stderr.write(i)
sys.stderr.flush()
raise
for i in unknown_args:
if i.startswith('-'):
if i in parse(True).parse_known_args()[1]:
_print(_('Unknown parameter'), i)
return 1
else:
_print(_('Unknown argument'), i)
return 1
param_object, steps = collect_object(None, param_object, view, args,
stdin_passwd=stdin_passwd)
if view.has_brief:
setattr(param_object, 'CheckOnly', True)
check_res = {}
while True:
method_result = getattr(metaObject, method_name)(metaObject, 0, param_object)
if not method_result:
print _('Method not available')
return None
if method_result[0].type and method_result[0].type != "pid":
check_res = check_result_msg(method_result, view, check_res,
args)
if not check_res:
return None
else:
param_object = get_param_pwd(check_res, view,
param_object,
stdin_passwd=stdin_passwd)
else:
break
view_obj = ViewInfo()
view_obj.step = None
view_obj.expert = True
view_obj.brief = True
view_obj.onlyhelp = False
view_obj.help_set = False
view_obj.conargs = [x[0] for x in args._get_kwargs() if x[1] is not None]
view_obj.dispatch_usenew = dispatch_usenew
try:
view = getattr(metaObject, method_view_name)(metaObject, 0, view_obj)
except AttributeError:
colorPrint.printERROR(_('Method not found: ') + method_name)
print_brief(view, steps.label)
for group in view.groups:
for field in group.fields:
if "error" in field.name:
return None
if not no_questions:
if stdin_passwd:
colorPrint.printERROR("Could not use the interactive mode. "
"Use option '-f' for run the process.")
return None
try:
ask = ResultViewer().askConfirm(_("Run process?"))
except KeyboardInterrupt:
ask = "no"
if ask.lower() in ['n', 'no']:
colorPrint.printERROR(_('Manually interrupted'))
return None
setattr(param_object, 'CheckOnly', False)
method_result = []
try:
check_res = {}
while True:
method_result = getattr(metaObject, method_name)(metaObject, 0, param_object)
if not method_result:
colorPrint.printERROR(_('method unavailable'))
return None
if method_result[0].type and method_result[0].type != "pid":
check_res = check_result_msg(method_result, view, check_res,
args)
if not check_res:
return None
else:
param_object = get_param_pwd(check_res, view,
param_object,
stdin_passwd=stdin_passwd)
else:
break
except VariableError, e:
_print(e)
return None
#for ReturnedMessage in method_result:
# if ReturnedMessage.type and ReturnedMessage.type != "pid":
# display_error(ReturnedMessage, args, view.groups)
# # params_text = ''
# # for Group in view.groups:
# # for field in Group.fields:
# # if field.name == ReturnedMessage.field:
# # params_text += getErrorOnParam(args, field)
# # colorPrint.printERROR('\r' + params_text % \
# # str(ReturnedMessage.message))
# return None
return method_result
def create_param_object(view):
param_object = type('collect_object', (object,), {})
param_object.CheckAll = True
param_object._type_info = {}
for Group in view.groups:
if not Group.fields:
continue
for field in Group.fields:
setattr(param_object, field.name, None)
param_object._type_info[field.name] = None
return param_object
def print_brief(view, brief_label):
for Group in view.groups:
if Group.name:
if not Group.fields:
continue
print_brief_group(Group.fields, Group.name)
class ColorTable(tableReport):
def __init__(self, head, body, printer, head_printer=None,
line_printer=None, body_printer=None):
super(ColorTable, self).__init__(None, head, body, colSpan=0)
self.default_printer = printer
self.line_printer = line_printer or printer
self.head_printer = head_printer or printer
self.body_printer = body_printer or printer
self.head = head
self.body = body
class Display(object):
def __init__(self):
self._print = get_terminal_print(color_print().defaultPrint)
def print_info(self, label, value):
GREEN = TextState.Colors.GREEN
self.display_asterisk(GREEN)
self._print(_("%s: ") % label)
WHITE = TextState.Colors.WHITE
self._print.foreground(WHITE)(value)
self._print("\n")
def print_label(self, label):
GREEN = TextState.Colors.GREEN
self.display_asterisk(GREEN)
self._print(_("%s: ") % label)
self._print("\n")
def display_asterisk(self, color):
self._print(" ")
self._print.foreground(color).bold("*")
self._print(" ")
def print_error(self, message):
RED = TextState.Colors.RED
self.display_asterisk(RED)
self._print(message)
self._print("\n")
def print_warning(self, message):
YELLOW = TextState.Colors.YELLOW
self.display_asterisk(YELLOW)
self._print(message)
self._print("\n")
def print_table(self, data, head):
WHITE = TextState.Colors.WHITE
ColorTable(head, data, self._print,
body_printer=self._print.foreground(
WHITE).clone()).printReport(False)
# sys.stdout.write('%s\n' % printTable(data, head))
def print_group(self, label):
self._print(label)
self._print("\n")
class InformationElement(object):
def __init__(self, field, display):
self.value = ""
self.label = ""
self.display = display
@classmethod
def from_field(cls, field, display):
if field.type == 'steps':
return None
map_elements = {'input': ValueInfo,
'openfile': ValueInfo,
'combo': ChoiceInfo,
'comboEdit': ChoiceInfo,
'radio': ChoiceInfo,
'file': ChoiceInfo,
'multichoice': MultiChoiceInfo,
'multichoice_add': MultiChoiceInfo,
'selecttable': MultiChoiceInfo,
'selecttable_add': MultiChoiceInfo,
'error': ErrorInfo,
'check': CheckInfo,
'check_tristate': CheckInfo,
'table': TableInfo
}
if field.element in map_elements:
return map_elements[field.element](field, display)
return None
def show(self):
self.display.print_info(self.label, self.value)
class ValueInfo(InformationElement):
def __init__(self, field, display):
super(ValueInfo, self).__init__(field, display)
self.value = field.value or ''
self.label = field.label
class CheckInfo(InformationElement):
def __init__(self, field, display):
super(CheckInfo, self).__init__(field, display)
self.label = field.label
map_answer = {'on': _('yes'), 'off': _("no"), 'auto': _('auto')}
self.value = map_answer.get(field.value, field.value)
class ChoiceInfo(InformationElement):
def __init__(self, field, display):
super(ChoiceInfo, self).__init__(field, display)
self.label = field.label or ''
if field.choice and field.comments:
map_comment = dict(zip(field.choice, field.comments))
self.value = map_comment.get(field.value, field.value) or ''
else:
self.value = field.value if field.value else ''
class MultiChoiceInfo(InformationElement):
def __init__(self, field, display):
super(MultiChoiceInfo, self).__init__(field, display)
self.label = field.label or ''
if field.listvalue:
value = field.listvalue
# удалить пустой первый элемент (особенности wsdl)
if value and not value[0]:
value.pop(0)
if field.choice and field.comments:
map_comment = dict(zip(field.choice, field.comments))
else:
map_comment = {}
self.value = ", ".join([map_comment.get(x, x) or '' for x in value])
else:
self.value = field.value or ""
class ErrorInfo(InformationElement):
def __init__(self, field, display):
super(ErrorInfo, self).__init__(field, display)
self.label = field.label
def show(self):
self.display.print_error(self.label)
class TableInfo(InformationElement):
"""
Табличная информация
"""
def map_row(self, row, typedata):
map_answer = {'on': _('yes'), 'off': _("no"), 'auto': _('auto')}
for cell, typefield in izip(row, typedata):
if typefield in ['check', 'check_tristate']:
yield map_answer.get(cell, cell) or ""
elif "password" in typefield:
yield "***"
else:
yield cell or ""
def __init__(self, field, display):
super(TableInfo, self).__init__(field, display)
self.label = field.label
self.head = field.tablevalue.head
# удаление первого элемента строки (для wsdl)
body = [x[1:] if x and not x[0] else x for x in field.tablevalue.body]
if not filter(None, map(lambda x: x, body)):
self.body = None
else:
type_values = [x.typefield for x in field.tablevalue.values]
self.body = [list(self.map_row(x, type_values)) for x in body]
def show(self):
if self.body:
self.display.print_label(self.label)
self.display.print_table(self.body, self.head)
def print_brief_group(Fields, group_name):
display = Display()
show_group = True
try:
for element in ifilter(None,
(InformationElement.from_field(
FieldAdapter.from_detect(x),
display)
for x in Fields if not x.uncompatible)):
if show_group:
display.print_group(group_name)
show_group = False
element.show()
except Exception:
import traceback
traceback.print_exc()
raise
class Methods(LocalCall.Common, object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Methods, cls).__new__(
cls, *args, **kwargs)
return cls._instance
def __init__(self):
LocalCall.Common.__init__(self, False, False, False, False)
def has_force_arg(args):
"""
Содержат ли аргумент force. Предварительное определение, так как на 100%
невозможно определить является ли -sf двумя опциями -s,-f или это одна
опция -s со значением "f"
:param args:
:return:
"""
force_parser = argparse.ArgumentParser(add_help=False)
force_parser.add_argument(
'-f', '--force', default=False, dest='force', action="store_true")
_args, _drop = force_parser.parse_known_args(args)
if _args.force:
return True
re_force = re.compile("^--force|-[a-zA-Z0-9]*f[a-zA-Z0-9]*$")
for arg in args:
if re_force.search(arg):
return True
else:
return False

@ -1,784 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import os
import argparse
import re
from calculate.lib.utils.common import getpass
from calculate.lib.cl_print import color_print
from calculate.lib.cl_lang import setLocalTranslate
from calculate.core.server.api_types import TableAdapter
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
from itertools import *
from api_types import ViewInfoAdapter, ArrayReturnedMessage, FieldAdapter
from calculate.lib.utils.colortext import get_terminal_print, TextState
colorPrint = color_print()
class GotErrorField(Exception):
"""
Исключение о получение поля error среди
элементов view
"""
pass
class BoolAction(argparse.Action):
reTrue = re.compile("^(?:on|yes)$", re.I)
reFalse = re.compile("^(?:off|no)$", re.I)
available_values = ("on", "off","yes", "no")
def __init__(self, option_strings, dest, nargs="?",
const=None, default=None, type=None, choices=None,
required=False, help=None, metavar=None):
super(BoolAction, self).__init__(
option_strings=option_strings, dest=dest,
nargs=nargs, const=const, default=default,
type=type, choices=choices, required=required,
help=help, metavar=metavar)
def get_values(self, value):
value = value.lower()
for v in self.available_values:
if value == v:
return v
else:
return ""
def __call__(self, parser, ns, values, option_string=None):
if values is None:
values = "on"
else:
if self.reTrue.match(values):
values = "on"
if self.reFalse.match(values):
values = "off"
values = self.get_values(values)
if not values:
msg = _('the value may be {0}').format(
formatListOr(self.available_values))
parser.error(msg)
setattr(ns, self.dest, values)
class BoolAutoAction(BoolAction):
available_values = ("on", "off", "yes", "no", "auto")
def _print(*args):
print " ".join(map(lambda x: _u8(x), args))
def get_password(text1=None, text2=None, getfromstdin=False,
needrepeat=True):
if getfromstdin:
try:
passwd = ''
while not passwd:
passwd = sys.stdin.readline()
if not passwd:
return None
passwd = passwd.rstrip('\n')
return passwd
except BaseException:
return None
if not text1:
text1 = _('Password: ')
if not text2:
text2 = _('Repeat: ')
try:
pass1 = 'password'
pass2 = 'repeat'
while pass1 != pass2:
pass1 = getpass.getpass(text1)
if not needrepeat:
return pass1
pass2 = getpass.getpass(text2)
if pass1 != pass2:
print _('Passwords do not match')
except KeyboardInterrupt:
return None
passwd = pass1 if (pass1 and pass1 == pass2) else ''
return passwd
def listToArray(client, _list, _type='string'):
if not client:
return _list
array = client.factory.create('%sArray' % _type)
for i in _list:
array['%s' % _type].append(i)
return array
def listToArrayArray(client, _list, _type='string'):
if not client:
return _list
array_array = client.factory.create('%sArrayArray' % _type)
for i in _list:
array = client.factory.create('%sArray' % _type)
for j in i:
array[_type].append(j)
array_array['%sArray' % _type].append(array)
return array_array
def _getattr(obj, attr):
return getattr(obj, attr) if hasattr(obj, attr) else None
import argparse
import textwrap as _textwrap
from calculate.lib.utils.text import get_term_size, _u, _u8, _uu8, formatListOr
class RawAndDefaultsHelpFormatter(argparse.HelpFormatter):
def __init__(self, prog, max_help_position=24, **kwargs):
# Use the whole terminal width
height, width = get_term_size()
argparse.HelpFormatter.__init__(self, prog, width=width,
max_help_position=max_help_position,
**kwargs)
def _split_lines(self, text, width):
text = self._whitespace_matcher.sub(' ', _u(text)).strip()
return _uu8(*_textwrap.wrap(text, width))
def get_method_argparser(view, args, cl_core=False):
"""
Get argparser by ViewInfo get from WSDL server (or stub)
cl_core - argparser for cl_core (local call)
"""
error_flag = False
method = args.method
if cl_core:
progr = os.path.basename(sys.argv[0])
else:
progr = 'cl-console --method ' + method
bool_vars = ["f"]
def fix_bool_variables(args):
prevlen = 0
local_args = args
while prevlen != len(local_args):
prevlen = len(local_args)
local_args = reduce(lambda x, y: (
x + [y[:2], "-%s" % y[2:]]
if (len(y) > 2 and y[:1] == "-" and y[1:2] in bool_vars and
not y[2:].lower().startswith("on") and
not y[2:].lower().startswith("off"))
else x + [y]), local_args, [])
return local_args
def get_list(data):
if data is not None:
for entry in data if cl_core else data[0]:
yield entry
parser = argparse.ArgumentParser(
prog=progr, add_help=False, formatter_class=RawAndDefaultsHelpFormatter)
parser.fixBoolVariables = fix_bool_variables
for Group in ifilter(lambda x: x.fields, get_list(view.groups)):
group = parser.add_argument_group(Group.name)
for field in get_list(Group.fields):
if field.element == 'error':
error_flag = True
colorPrint.printERROR(field.label)
elif field.opt:
opt = field.opt
data = {'dest': field.name, 'help': opt.help}
if "choice" in field.type and hasattr(field.opt, "syntax") and \
field.opt.syntax and "{" in field.opt.syntax:
lgroup = group.add_mutually_exclusive_group()
help = dict(map(lambda x: (x[0].strip("'"), x[2]),
map(lambda x: x.partition(' - '),
field.help.split(',\n'))))
choice = field.choice
if not type(choice) in (list, tuple):
choice = choice.string
for val in filter(None, choice):
data['action'] = 'store_const'
# data['nargs'] = '?'
data['const'] = val
data['metavar'] = ""
if hasattr(field, "value") and field.value == val:
data['help'] = (help.get(val, field.help) +
" " + _("(by default)"))
else:
data['help'] = help.get(val, field.help)
lgroup.add_argument(field.opt.syntax.format(choice=val),
**data)
continue
if "password" in field.type:
data['action'] = "store_true"
if "need" in field.type:
data['help'] = argparse.SUPPRESS
else:
data['type'] = str
if field.element in ['check', 'check_tristate']:
if field.element == "check_tristate":
data['action'] = BoolAutoAction
else:
data['action'] = BoolAction
if field.value == 'on':
data['help'] = data['help'] + " " + _(
"(enabled by default)")
if opt.shortopt:
bool_vars.append(opt.shortopt[1])
elif field.element == 'radio' and field.type == 'bool':
data['action'] = BoolAction
if field.value == 'on':
data['help'] = data['help'] + " " + _(
"(enabled by default)")
if opt.shortopt:
bool_vars.append(opt.shortopt[1])
if field.element == 'table' and field.type != 'steps':
data['action'] = 'append'
if data.get('action') != "store_true":
data['metavar'] = opt.metavalue if opt.metavalue \
else field.name.upper()
# if ':' in data['metavar']:
# data['metavar'] = field.name.upper()
if "choice" in field.type:
if "list" in field.type:
data['help'] = "%s (%s)" % (
data['help'],
_("'list' for displaying possible values, "
"'none' is never one"))
else:
data['help'] = "%s (%s)" % (
data['help'],
_("'list' for displaying possible values"))
if "boolauto" in field.type:
data['metavar'] = "ON/OFF/AUTO"
elif "bool3" in field.type:
data['metavar'] = "ON/OFF/AUTO"
elif "bool" in field.type:
data['metavar'] = "ON/OFF"
try:
opts = filter(None, [opt.shortopt, opt.longopt])
if any("-" not in x for x in opts):
data.pop('dest')
data['nargs'] = '?'
group.add_argument(*opts, **data)
except argparse.ArgumentError:
continue
group = parser.add_argument_group(_("Common arguments"))
group.add_argument(
'-f', '--force', action='store_true', default=False,
dest='no_questions', help=_('silent during the process'))
if error_flag:
raise GotErrorField
return parser
def set_obj_item(client, param_object, field_name, value):
"""
Set value for Info object. By client detect (local or WSDL call)
"""
if client:
param_object.__setitem__(field_name, value)
else:
setattr(param_object, field_name, value)
return param_object
def set_table_pwd(client, param_object, field, value):
if type(field.tablevalue.values) in [list, tuple]:
choice_values = field.tablevalue.values
# column = len(field.tablevalue.head)
else:
choice_values = field.tablevalue.values.ChoiceValue
# column = len(field.tablevalue.head.string)
# print ChoiceValue, column
found_flag = False
changed_string = None
if not getattr(param_object, field.name):
for column in range(len(choice_values)):
if found_flag:
break
if "password" in choice_values[column].typefield:
if hasattr(field.tablevalue.body, 'stringArray'):
body = field.tablevalue.body.stringArray
else:
body = field.tablevalue.body
for _row in body:
if hasattr(_row, 'string'):
row = _row.string
else:
if not _row[0]:
row = _row[1:]
else:
row = _row
if not row[column]:
row[column] = value
temp = []
for item in row:
temp.append(item) if item else temp.append('')
changed_string = temp
found_flag = True
break
else:
user_table = getattr(param_object, field.name)
if hasattr(user_table, 'stringArray'):
user_table = user_table.stringArray
for column in range(len(choice_values)):
if found_flag:
break
if "password" in choice_values[column].typefield:
for _row in user_table:
if hasattr(_row, 'string'):
row = _row.string
else:
if not _row[0]:
row = _row[1:]
else:
row = _row
if not row[column]:
row[column] = value
temp = []
for item in row:
temp.append(item) if item else temp.append('')
changed_string = temp
found_flag = True
break
# код выполняется через сетевую консоль
if client:
if not getattr(param_object, field.name):
setattr(param_object, field.name, field.tablevalue.body)
object_array = TableAdapter.get_matrix(param_object[field.name])
# код выполняется локально
else:
if not getattr(param_object, field.name):
setattr(param_object, field.name,
map(lambda x: x[1:] if not x[0] else x,
field.tablevalue.body))
object_array = getattr(param_object, field.name)
result = []
for _array in object_array:
temp = []
for item in _array:
temp.append(item) if item else temp.append('')
result.append(temp)
if changed_string:
for item in result:
if str(item[0]) == str(changed_string[0]):
result.remove(item)
result.append(changed_string)
if client:
param_object[field.name] = listToArrayArray(client, result)
else:
setattr(param_object, field.name, result)
return param_object
def display_error(error, args, groups):
params_text = ''
sys.stdout.write('\r')
sys.stdout.flush()
list_answer = False
varname, comments, values, value, list_value = None, None, None, None, []
if error.type != "commonerror":
for group in groups:
for field in group.fields:
if field.name == error.field:
if args is not None:
if (getattr(args, field.name) == "list" and
"choice" in field.type):
if error.field_obj:
field_obj = FieldAdapter.from_detect(error.field_obj)
list_answer = True
varname = (field_obj.label or
field_obj.name)
comments = field_obj.comments
values = field_obj.choice
value = field_obj.value
list_value = error.field_obj.listvalue or []
params_text += getErrorOnParam(args, field)
else:
if field.opt.shortopt or field.opt.longopt:
params_text += _('Wrong option ')
params_text += ' ' + ', '.join(
filter(None, [field.opt.shortopt,
field.opt.longopt])) + '. %s'
if list_answer:
__print = get_terminal_print(colorPrint.defaultPrint)
__print.foreground(TextState.Colors.WHITE)(
_("%s values:") % varname)
__print("\n")
if comments and values:
maxlen = len(max(values, key=len))
for v, c in zip(values, comments):
if not v and not c:
continue
__print(" ")
__print.bold("[" + v + "]")
__print(" " * (maxlen - len(v)))
__print(" ")
__print(c)
if value == v or v in list_value:
__print(" ")
__print.bold.foreground(TextState.Colors.WHITE)("*")
__print("\n")
if not comments:
for v in filter(None, values):
__print(" ")
__print.bold("[" + v + "]")
if value == v:
__print(" ")
__print.bold.foreground(TextState.Colors.WHITE)("*")
__print("\n")
elif error.type != "commonerror":
colorPrint.printERROR(params_text % error.message)
else:
colorPrint.printWARNING(error.message)
def check_result_msg(method_result, view, input_error_dict=None, args=None):
if not input_error_dict:
input_error_dict = {}
password_errors = {}
method_result = ArrayReturnedMessage.from_detect(method_result)
view = ViewInfoAdapter.from_detect(view)
for error in method_result:
if error.type == 'pwderror':
password_errors[error.field] = error.message
continue
display_error(error, args, view.groups)
# если все ошибки связаны с паролем
if len(password_errors) == len(method_result):
if (not dict([x for x in input_error_dict.items()
if x not in password_errors.items()]) and
not dict([x for x in password_errors.items()
if x not in input_error_dict.items()])):
return None
return password_errors
else:
return None
def get_param_pwd(check_res, view, param_object, client=None,
stdin_passwd=False):
view = ViewInfoAdapter.from_detect(view)
for pwd_field in check_res:
if not stdin_passwd:
_print(check_res[pwd_field])
for group in view.groups:
for field in group.fields:
if field.name == pwd_field:
if field.element == 'table':
value = get_password(getfromstdin=stdin_passwd)
if value is None:
_print(check_res[pwd_field])
raise KeyboardInterrupt
set_table_pwd(client, param_object, field, value)
else:
value = get_password(getfromstdin=stdin_passwd)
if value is None:
_print(check_res[pwd_field])
raise KeyboardInterrupt
setattr(param_object, pwd_field, value)
return param_object
def collect_object(client, param_object, view, args, wait_thread=None,
stdin_passwd=False):
"""
Collect Info object by args
"""
steps = None
view = ViewInfoAdapter.from_detect(view)
for group in view.groups:
for field in group.fields:
#if field.uncompatible:
# continue
if (field.element in ['check', 'check_tristate'] and
field.type in ('bool', 'boolauto', 'bool3')) or (
field.element == 'radio' and field.type == 'bool'):
value = _getattr(args, field.name)
if field.type == 'bool3':
pass
else:
if value:
if _getattr(args, field.name).lower() in ['on', 'yes']:
value = True
elif _getattr(args,
field.name).lower() in ['off', 'no']:
value = False
else:
value = None
else:
value = None
param_object = set_obj_item(client, param_object,
field.name, value)
elif (field.element == 'input' and
field.name in ['cl_page_offset', 'cl_page_count']):
val = _getattr(args, field.name)
if not val:
val = 0
if wait_thread:
wait_thread.stop()
# param_object[field.name] = val
param_object = set_obj_item(client, param_object, field.name,
val)
elif field.element in ['input', 'openfile',
'file', 'radio', 'combo', 'comboEdit']:
param_object = set_obj_item(client, param_object, field.name,
_getattr(args, field.name))
elif 'passw' in field.element and _getattr(args, field.name) \
or field.type and "need" in field.type:
if wait_thread:
wait_thread.pause()
label = field.label or _("Password")
password = get_password(label + _(": "),
_('Repeat password: '),
getfromstdin=stdin_passwd,
needrepeat="one" not in field.type)
if password is None:
raise KeyboardInterrupt
param_object = set_obj_item(client, param_object, field.name,
password)
if wait_thread:
wait_thread.resume()
elif field.element in ['multichoice', 'multichoice_add',
'selecttable', 'selecttable_add']:
val = _getattr(args, field.name)
if val in ['off', 'none']:
if client:
value = listToArray(client, [None])
else:
value = []
else:
value = listToArray(client,
val.split(',')) if val else None
param_object = set_obj_item(client, param_object, field.name,
value)
elif field.element == 'table' and field.type != 'steps':
val = _getattr(args, field.name)
value = collect_table(field, val, client, wait_thread,
stdin_passwd)
param_object = set_obj_item(client, param_object, field.name,
value)
elif field.element == 'table' and field.type == 'steps':
steps = field
if hasattr(param_object, 'CheckAll'):
param_object = set_obj_item(client, param_object, 'CheckAll', True)
return param_object, steps
def convertArgDictToList(argDict):
"""
Convert list of dict like {'arg_1':None,'arg_2':'value2','arg_5':'value5'}
to [..,['','value2','','','value5']..] (iterator)
"""
for row in argDict:
yield [row[i] or '' for i in sorted(row.keys())]
def collect_table(field, val_list, client, wait_thread=None,
stdin_passwd=False):
def split_param(l, delimeter=","):
for x in l:
for y in x.split(delimeter):
yield y
if not val_list:
return None
# if specified syntax for table row
if hasattr(field.opt, "syntax") and field.opt.syntax:
reArgs = re.compile(field.opt.syntax)
# check for correct sentense
for wrong in ifilterfalse(reArgs.search, val_list):
# raise Error on wrong
raise ValueError(_("Wrong %s value syntax") %
(field.opt.shortopt or field.opt.longopt)
+ " " + wrong)
# create groupdict from all vals
argDict = map(lambda x: x.groupdict(), map(reArgs.search, val_list))
# convert groupdicts to val_table
val_table = list(convertArgDictToList(argDict))
# standard syntax
else:
reduced_list = list(val_list)
val_table = map(lambda x: x.split(':'), reduced_list)
if type(field.tablevalue.values) in [list, tuple]:
choiceValue = field.tablevalue.values
else:
choiceValue = field.tablevalue.values.ChoiceValue
choiceValue = filter(lambda x: x.typefield != 'readonly', choiceValue)
lenChoiceValue = len(choiceValue)
for wrong in ifilter(lambda x: len(x) > lenChoiceValue,
val_table):
if type(wrong) in (list, tuple):
wrong = ":".join(wrong)
raise ValueError(_("Wrong %s value syntax") %
(field.opt.shortopt or field.opt.longopt)
+ " " + wrong)
# obj_body = []
# if type(field.tablevalue.body) == list:
# temp_body = field.tablevalue.body
# else:
# temp_body = field.tablevalue.body.stringArray
# for obj_row in temp_body:
# if type(obj_row) != list:
# obj_row = obj_row.string
# for item in range(len(obj_row)):
# if not obj_row[item]:
# obj_row[item] = ''
# else:
# if obj_row:
# if obj_row[0] == '':
# obj_row.pop(0)
# obj_body.append(obj_row)
#
# obj_body = collect_obj_body(obj_body, field)
is_password_get = any('password' in x.typefield for x in choiceValue)
obj_body = []
for line in val_table:
received_password = None
if is_password_get:
if len(line) > 0 and line[0].lower() != '':
if wait_thread:
wait_thread.stop()
sys.stdout.write('\r')
sys.stdout.flush()
received_password = get_password(
_('Password for %s: ') % line[0],
_('Repeat password for %s: ') % line[0],
getfromstdin=stdin_passwd)
if received_password is None:
raise KeyboardInterrupt
temp_row = []
for val, choice_value in izip_longest(
line, filter(lambda x: x.typefield != 'readonly', choiceValue),
fillvalue=''):
typefield = choice_value.typefield
# if readonly, except first column
if typefield in ['check', 'check_tristate']:
if BoolAction.reTrue.match(val):
temp_row.append('on')
elif BoolAction.reFalse.match(val):
temp_row.append('off')
else:
temp_row.append(val)
elif typefield in ['input', 'combo', 'comboEdit', 'openfile',
'file', 'radio', 'text', 'multichoice',
'multichoice_add']:
temp_row.append(val)
elif typefield == 'password':
if received_password is not None:
temp_row.append(received_password)
else:
temp_row.append(val)
obj_body.append(temp_row)
if not obj_body:
obj_body = [[None]]
return listToArrayArray(client, obj_body)
def collect_obj_body(body, field):
field = FieldAdapter.from_detect(field)
column = len(field.tablevalue.head)
result_table = []
choice_value = field.tablevalue.values
for i in range(len(body)):
temp_row = []
for j in range(column):
# not adding if readonly
if j > (len(choice_value) + 1):
continue
typefield = choice_value[j].typefield
if typefield == 'readonly' and j > 0:
continue
elif typefield in ['check', 'check_tristate']:
if len(body[i]) < j + 1:
temp_row.append('')
continue
if not body[i][j]:
temp_row.append('')
elif body[i][j].lower() in ['on', 'yes']:
temp_row.append('on')
elif body[i][j].lower() in ['off', 'no']:
temp_row.append('off')
else:
temp_row.append(body[i][j])
elif typefield in ['input', 'combo', 'comboEdit', 'openfile',
'file', 'password', 'radio', 'text']:
if len(body[i]) < j + 1:
temp_row.append('')
elif not body[i][j]:
temp_row.append('')
else:
temp_row.append(body[i][j])
elif typefield in ['multichoice', 'multichoice_add']:
if len(body[i]) < j + 1:
temp_row.append('')
elif not body[i][j]:
temp_row.append('')
else:
temp_row.append(body[i][j])
result_table.append(temp_row)
return result_table
def getErrorOnParam(args, field):
"""
Get errors for param
"""
params_text = ""
if any("-" in x
for x in filter(None, (field.opt.longopt, field.opt.shortopt))):
param_name = ', '.join(filter(None,
[field.opt.shortopt, field.opt.longopt]))
else:
param_name = field.opt.metavalue
if getattr(args, field.name) is None and "need" not in field.type:
params_text += "%s. " + _("Use the parameter") + " "
params_text += param_name + '. '
else:
if "need" in field.type:
params_text += \
_('Error in field \'%s\'. ') % field.label + " %s"
elif getattr(args, field.name) == "list" and "choice" in field.type:
params_text += "%s"
else:
params_text += _('Error in parameter ')
params_text += param_name + '. %s'
return params_text

@ -1,60 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2011-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime
import threading
from cert_cmd import find_cert_id
# Time life certificate in days
DAY_CERT = 600
def serv_post_cert(cls):
""" transfer the client certificate """
cur_thread = threading.currentThread()
certificate = cur_thread.client_cert
if certificate is None:
return [-3]
checked_id = find_cert_id(certificate, cls.data_path, cls.certbase)
try:
if int(checked_id) < 1:
return [-2]
except ValueError:
return [-4]
results = []
with open(cls.certbase) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
# and each word in line
words = line.split()
# if in line present certificate id
if len(words) > 3:
if words[0] == checked_id:
results.append(checked_id)
date = datetime.datetime.strptime(
words[2] + ' ' + words[3], '%Y-%m-%d %H:%M:%S.%f')
d = datetime.datetime.now() - date
v = DAY_CERT - d.days # How many days left certificate
if v < 0:
# Method deleted certificate
v = -2 # expiry date has passed
# For a long time, is not displayed to the client
elif v > 60:
v = -1
results.append(v)
return results
return [-4]

@ -1,412 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from spyne.server.wsgi import WsgiApplication
import re
import logging
import os
#cStringIO was moved to io in python3
import cStringIO as io
logger = logging.getLogger(__name__)
import datetime
import pickle
from loaded_methods import LoadedMethods
# for OpenSSLAdapter
import calculate.contrib
from cherrypy.wsgiserver.ssl_pyopenssl import pyOpenSSLAdapter
HTTP_500 = '500 Internal server error'
HTTP_200 = '200 OK'
HTTP_405 = '405 Method Not Allowed'
HTTP_403 = '403 Forbidden'
not_log_list = ['post_server_request', 'post_client_request', 'del_sid',
'get_server_cert', 'get_client_cert', 'get_entire_frame',
'get_crl', 'get_server_host_name', 'get_ca', 'get_table',
'post_cert', 'post_sid', 'active_client', 'list_pid',
'get_methods', 'get_frame', 'get_progress', 'pid_info']
class ClApplication(WsgiApplication):
def __init__(self, app, log=None):
super(ClApplication, self).__init__(app)
# add object logging
self.log = logger
#verification of compliance certificate and session (sid)
def check_cert_sid(self, sid, server):
import threading
curthread = threading.currentThread()
cert = curthread.client_cert
from cert_cmd import find_cert_id
cert_id = find_cert_id(cert, server.data_path, server.certbase)
cert_id = int(cert_id)
if cert_id == 0:
return 0
# session file
if not os.path.exists(server.sids):
os.system('mkdir %s' % server.sids)
if not os.path.isfile(server.sids_file):
open(server.sids_file, 'w').close()
with open(server.sids_file, 'r') as fd:
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (IOError, EOFError, KeyError):
break
# find session id in sids file
if cert_id == int(list_sid[1]):
if int(sid) == int(list_sid[0]):
return 1
return 0
# input parameters - certificate and name method
def check_rights(self, method_name, req_env, sid):
""" check right client certificate for the method """
import OpenSSL
# rmethod = re.compile('[{\w]+[}]')
# method_rep = rmethod.findall(method_name)
# method_name = method_name.replace(method_rep[0], '')
import threading
curthread = threading.currentThread()
cert = curthread.client_cert
server_cert = curthread.server.ssl_certificate
server_key = curthread.server.ssl_private_key
certbase = curthread.server.certbase
rights = curthread.server.rights
group_rights = curthread.server.group_rights
data_path = curthread.server.data_path
permitted_methods = ['post_server_request', 'post_client_request',
'get_server_cert', 'get_client_cert',
'get_crl', 'get_server_host_name', 'get_ca']
if method_name in permitted_methods:
return 1
if cert is None:
if method_name not in permitted_methods:
return 0
return 1
if (sid and
(method_name in LoadedMethods.rightsMethods or
method_name.endswith('_view') and
method_name[:-5] in LoadedMethods.rightsMethods)):
if not self.check_cert_sid(sid, curthread.server):
return 0
with open(server_cert, 'r') as f:
data_server_cert = f.read()
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, data_server_cert)
with open(server_key, 'r') as f:
data_server_key = f.read()
Pkey = OpenSSL.crypto.load_privatekey(OpenSSL.SSL.FILETYPE_PEM,
data_server_key, 'qqqq')
signature = OpenSSL.crypto.sign(Pkey, cert, 'SHA1')
try:
OpenSSL.crypto.verify(certobj, signature, cert, 'SHA1')
except Exception as e:
print e
return 0
if method_name == 'cert_add':
return 0
certobj_cl = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, cert)
try:
com = certobj_cl.get_extension(certobj_cl.get_extension_count() - 1)
groups = com.get_data().split(':')[1]
except IndexError:
groups = ""
except Exception:
return 0
groups_list = groups.split(',')
# open certificates database
if not os.path.exists(certbase):
open(certbase, "w").close()
from cert_cmd import find_cert_id
checked_id = find_cert_id(cert, data_path, certbase)
cert_id = int(checked_id)
count = 0
find_flag = False
# if certificate found
if cert_id > 0:
if method_name not in LoadedMethods.rightsMethods:
return 1
# if group = all and not redefined group all
if 'all' in groups_list:
find_flag = False
with open(group_rights, 'r') as fd:
t = fd.read()
# find all in group_rights file
for line in t.splitlines():
if not line:
continue
if line.split()[0] == 'all':
find_flag = True
break
# if not find_flag:
# return 1
for right_param in LoadedMethods.rightsMethods[method_name]:
flag = 0
try:
# check rights
if not os.path.exists(rights):
open(rights, 'w').close()
with open(rights) as fr:
t = fr.read()
for line in t.splitlines():
words = line.split()
# first word in line equal name input method
if words[0] == right_param:
for word in words:
try:
word = int(word)
except ValueError:
continue
# compare with certificat number
if cert_id == word:
# if has right
count += 1
flag = 1
break
if cert_id == -word:
return 0
if flag:
break
if flag:
break
# open file with groups rights
if not os.path.exists(group_rights):
open(group_rights, 'w').close()
with open(group_rights) as fd:
t = fd.read()
for line in t.splitlines():
if not line:
continue
words = line.split(' ', 1)
# first word in line equal name input method
if words[0] in groups_list:
methods = words[1].split(',')
for word in methods:
# compare with certificat number
if right_param == word.strip():
# if has right
count += 1
flag = 1
break
if flag:
break
except Exception:
return 0
if count == len(LoadedMethods.rightsMethods[method_name]):
return 1
if not find_flag and 'all' in groups_list:
return 1
elif method_name in ['post_cert', 'init_session']:
return 1
return 0
def create_path(self):
""" create paths for server files """
import threading
curthread = threading.currentThread()
data_path = curthread.server.data_path
sids = curthread.server.sids
pids = curthread.server.pids
cert_path = curthread.server.cert_path
if not os.path.exists(sids):
if not os.path.exists(data_path):
os.makedirs(data_path)
os.makedirs(sids)
if not os.path.exists(pids):
if not os.path.exists(data_path):
os.makedirs(data_path)
os.makedirs(pids)
if not os.path.exists(data_path + '/conf'):
if not os.path.exists(data_path):
os.makedirs(data_path)
os.makedirs(data_path + '/conf')
if not os.path.exists(data_path + '/conf/right.conf'):
open(data_path + '/conf/right.conf', 'w').close()
if not os.path.exists(data_path + '/conf/group_right.conf'):
open(data_path + '/conf/group_right.conf', 'w').close()
if not os.path.exists(data_path + '/client_certs'):
os.makedirs(data_path + '/client_certs')
if not os.path.exists(data_path + '/server_certs'):
os.makedirs(data_path + '/server_certs')
if not os.path.exists(cert_path):
os.makedirs(cert_path)
def get_method_name_from_http(self, http_req_env):
retval = None
# check HTTP_SOAPACTION
retval = http_req_env.get("HTTP_SOAPACTION")
if retval is not None:
if retval.startswith('"') and retval.endswith('"'):
retval = retval[1:-1]
if retval.find('/') >0:
retvals = retval.split('/')
retval = '{%s}%s' % (retvals[0], retvals[1])
logger.debug("\033[92m"
"Method name from HTTP_SOAPACTION: %r"
"\033[0m" % retval)
if(not retval):
logger.critical("Couldn't get method name from HTTP_SOAPACTION")
return retval
def get_sid_from_soap(self, http_req_env):
"""
rips sid param from soap request (if there is one)
"""
if (not "wsgi.input" in http_req_env):
return None
length = http_req_env.get("CONTENT_LENGTH")
input = http_req_env["wsgi.input"]
body = input.read(int(length))
res = re.search("<ns.:sid>(.*?)<\/ns.:sid>", body)
#horrbile hack:
#cherrypy provides rfile in req_env which is consumed upon .read() without
# workarounds, and both we and spyne need the data on it
#so we pass a dummy with the data and read() method on to spyne
http_req_env["wsgi.input"] = io.StringIO(body)
if(res):
return int(res.group(1))
else:
return None
def handle_rpc(self, req_env, start_response):
"""
Overriding spyne.wsgiApplication method
"""
import OpenSSL
import threading
http_resp_headers = {
'Content-Type': 'text/xml',
'Content-Length': '0',
}
curthread = threading.currentThread()
curthread.REMOTE_ADDR = req_env.get('REMOTE_ADDR')
curthread.REMOTE_PORT = req_env.get('REMOTE_PORT')
ip = req_env.get('REMOTE_ADDR')
self.create_path()
sid = self.get_sid_from_soap(req_env)
method_name = self.get_method_name_from_http(req_env)
if method_name is None:
resp = "Could not extract method name from the request!"
http_resp_headers['Content-Length'] = str(len(resp))
start_response(HTTP_500, http_resp_headers.items())
return [resp]
service = self.app.services[0]
import threading
curthread = threading.currentThread()
# check if client certificate exists
if not hasattr(curthread, 'client_cert'):
curthread.client_cert = None
# check rights client certificate for the method
check = self.check_rights(method_name, req_env, sid)
if not check:
if curthread.client_cert:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, curthread.client_cert)
finger = certobj.digest('SHA1')
if self.log:
self.log.debug('%s %s %s forbidden %s'
% (datetime.datetime.now().__str__(),
finger, ip,
method_name[5:]))
resp = "Permission denied: " + method_name
http_resp_headers['Content-Length'] = str(len(resp))
start_response(HTTP_403, http_resp_headers.items())
return [resp]
if sid:
curthread.lang = service.get_lang(service, sid, method_name)
if curthread.client_cert:
certobj = OpenSSL.crypto.load_certificate(
OpenSSL.SSL.FILETYPE_PEM, curthread.client_cert)
finger = certobj.digest('SHA1')
if (not method_name[5:] in not_log_list and
not method_name[5:].endswith('_view')):
if self.log:
self.log.debug('%s %s %s allowed %s'
% (datetime.datetime.now().__str__(),
finger, ip,
method_name[5:]))
return super(ClApplication, self).handle_rpc(req_env, start_response)
class OpenSSLAdapter(pyOpenSSLAdapter):
def verify_func(self, connection, x509, errnum, errdepth, ok):
# get client certificate
import OpenSSL
import threading
curthread = threading.currentThread()
if errdepth == 0:
curthread.client_cert = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, x509)
else:
curthread.client_cert = None
return ok
def get_context(self):
"""Return an SSL.Context from self attributes."""
# See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442473
import OpenSSL
c = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD)
c.set_options(OpenSSL.SSL.OP_NO_SSLv2 | OpenSSL.SSL.OP_NO_SSLv3)
# c.set_passwd_cb(lambda *unused: 'qqqq')
c.use_privatekey_file(self.private_key)
c.set_verify(OpenSSL.SSL.VERIFY_PEER, self.verify_func)
if self.certificate_chain:
c.load_verify_locations(self.certificate_chain)
c.use_certificate_file(self.certificate)
return c

@ -1,105 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import calculate.contrib
from spyne.service import Service, ServiceMeta
from spyne import String, Integer, Array, rpc
from func import WsdlMeta
from api_types import ReturnedMessage, ViewInfo, ViewParams
from spyne.protocol._outbase import OutProtocolBase
from api_types import LazyString
#monkey patch:
def to_unicode(self, cls, value, *args, **kwargs):
if value is None:
return None
#### PATCH ####################
if isinstance(value, LazyString):
value = str(value)
###############################
handler = self._to_unicode_handlers[cls]
retval = handler(cls, value, *args, **kwargs)
return retval
OutProtocolBase.to_unicode = to_unicode
class ServiceMetaAdapter(ServiceMeta):
#ref to the created class
global_class_ref = None
#this is used for a localCall
class CoreInnerWsdl(ServiceMeta, WsdlMeta):
pass
# Nevermind, following is deprecated:
#the idea is to decorate methods that need rpc with this
#and then find them in make_service and wrap them in funcs without self ref
# def rpc_a():
# def func(f):
# f.wrap_rpc = True
# return f
# return func
#wraps a func in rpc decorator
#this is needed because Spyne service does not allow self ref in function calls
def make_rpc_func_view(func_to_call):
def _function(ctx, sid, params):
return func_to_call(ServiceMetaAdapter.global_class_ref, sid, params)
_function.__name__ = func_to_call.__name__
return rpc(Integer, ViewParams, _returns=ViewInfo)(_function)
def make_rpc_func_vars(func_to_call):
def _function(ctx, dv=None, params=None):
return func_to_call(ServiceMetaAdapter.global_class_ref, dv, params)
_function.__name__ = func_to_call.__name__
return staticmethod(_function)
def make_rpc_func_caller(func_to_call):
def _function(ctx, sid, params):
return func_to_call(ServiceMetaAdapter.global_class_ref, sid, params)
_function.__name__ = func_to_call.__name__
info_class = func_to_call.info_class
return rpc(Integer, info_class, _returns=Array(ReturnedMessage))(_function)
def make_service(basic_class, wsdl_core_class_list, outer_wsdl_class_list, service_name):
#for Core, rpc methods only present in basic_class, we need others just to have a mono class
#for outer wsdl classes, we have to add stateless wrap methods on our own
saved_pub_methods = basic_class.public_methods
functions_to_add = {}
for klass in outer_wsdl_class_list:
for meth in klass.__dict__:
if not meth.startswith("__") and not meth == "methods":
if meth.endswith("_view"):
functions_to_add[meth] = make_rpc_func_view(getattr(klass, meth))
elif meth.endswith("_vars"):
functions_to_add[meth] = make_rpc_func_vars(getattr(klass, meth))
else:
functions_to_add[meth] = make_rpc_func_caller(getattr(klass, meth))
functions_to_add.update({"__metaclass__" : ServiceMetaAdapter})
ClService = ServiceMetaAdapter(service_name, tuple([basic_class] + wsdl_core_class_list), functions_to_add)
ClService.public_methods.update(saved_pub_methods)
#TODO replace with a single ref
ServiceMetaAdapter.global_class_ref = ClService
basic_class.set_comb_class_ref(ClService)
return ClService

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2011-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import action
import core
import request
import certificate
import groups
import setup_package
import variable
import backup
section = "core"

@ -1,167 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0 #
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from os import path
from calculate.lib.datavars import (Variable, ReadonlyVariable)
from calculate.lib.utils.files import get_free_dirname, listDirectory
from calculate.lib.cl_lang import setLocalTranslate
import datetime
from action import Actions
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
class VariableClBackupPath(Variable):
"""
Путь до каталога, где будет подготавливаться backup
"""
preferred_dn = '/var/calculate/tmp/backup_prepare'
def get(self):
return get_free_dirname(self.preferred_dn)
class VariableClBackupContentsName(Variable):
"""
Названия файла CONTENTS в архиве
"""
value_format = "CONTENTS"
class VariableClBackupRootName(Variable):
"""
Названия каталога, куда сохраняются конфигурационные файлы
"""
value_format = "root"
class VariableClBackupFileContents(ReadonlyVariable):
"""
CONTENTS в архиве настроек
"""
value_format = "{cl_backup_path}/{cl_backup_contents_name}"
class VariableClBackupIniEnv(Variable):
"""
Названия файла CONTENTS в архиве [install] init =
"""
value_format = "{cl_backup_path}/ini.env"
class VariableClBackupBasePath(Variable):
"""
Директория в которой будет создан архив
"""
value = "/var/calculate/backup"
class VariableClBackupTime(ReadonlyVariable):
"""
Переменная содержащая информацию: время создания backup
"""
def init(self):
self.label = _("Backup created")
def get(self):
backup_fn = self.Get('cl_backup_file')
if backup_fn and path.exists(backup_fn):
try:
dt = datetime.datetime.strptime(
path.basename(backup_fn).rpartition("-")[2],
"%Y%m%d%H%M%S.tar.bz2")
return dt.strftime("%s")
except ValueError:
pass
return ""
def humanReadable(self):
ts = self.Get()
if ts:
ret = []
backup_tm = datetime.datetime.fromtimestamp(int(ts))
now_tm = datetime.datetime.now()
backup_diff = now_tm - backup_tm
if backup_diff.days:
ret.append(_("%d days") % backup_diff.days)
minute = 60
hour = 60 * minute
times = backup_diff.seconds
if times >= hour:
ret.append(_("%d hours") % (times / hour))
times %= hour
if times >= minute:
ret.append(_("%d minutes") % (times / minute))
times %= minute
if times:
ret.append(_("%d seconds") % times)
return _("%s ago") % (" ".join(ret))
return _("Unknown")
class VariableClBackupFile(Variable):
"""
Путь до создаваемое архива резервной копии
"""
def init(self):
self.label = _("Backup file")
def get_backup(self):
"""
Получить путь для подготовки архива настроек
:return:
"""
dn = self.Get('cl_backup_base_path')
dt = datetime.datetime.now().strftime(
"calculate-backup-%Y%m%d%H%M%S.tar.bz2")
return path.join(dn, dt)
def get_restore(self):
"""
Получить путь для распаковки архива настроек
:return:
"""
dn = self.Get('cl_backup_base_path')
for fn in sorted((x for x in listDirectory(dn, fullPath=True)
if x.endswith(".tar.bz2")),
reverse=True):
# получить самый свежий файл
return fn
return ""
def get(self):
action = self.Get('cl_action')
if action == Actions.Backup:
return self.get_backup()
elif action == Actions.BackupRestore:
return self.get_restore()
class VariableClBackupVerboseSet(Variable):
"""
Verbose output for backup
"""
type = "bool"
opt = ["-v", "--verbose"]
value = "off"
def init(self):
self.help = _("verbose output")
self.label = _("Verbose output")

@ -1,794 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2011-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from calculate.lib.datavars import VariableError, DataVarsError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_core3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
import setup_package
import server.certificate as certificate
import server.groups as groups
import server.request as request
import set_vars
from backup import Backup, BackupError
from calculate.core.utils.cl_backup import ClBackupAction
from calculate.core.utils.cl_backup_restore import ClBackupRestoreAction
from calculate.core.server.func import WsdlBase
from calculate.core.utils.cl_core_setup import ClCoreSetupAction
from calculate.core.utils.cl_core_patch import ClCorePatchAction
from calculate.core.utils.cl_config import ClConfigAction
from calculate.core.utils.cl_core_dispatch import ClCoreDispatchAction
from calculate.core.utils.cl_core_view_cert import ClCoreViewCert
from calculate.core.utils.cl_core_group import (
ClCoreGroupShow, ClCoreGroupMod, ClCoreGroupAdd, ClCoreGroupDel)
from calculate.core.utils.cl_core_request import (
ClCoreRequestShow, ClCoreRequestConfirm, ClCoreRequestDel)
from calculate.core.utils.cl_core_variables import (ClCoreVariables,
ClCoreVariablesShow)
from calculate.core.utils.cl_core_custom import ClCoreCustomAction
from calculate.core.utils.cl_core_restart import ClCoreRestartAction
from calculate.core.variables.action import Actions
class Wsdl(WsdlBase):
methods = [
#
# Настройка пакета во время установки (cl-core-setup)
#
{
# идентификатор метода
'method_name': "core_setup",
# категория метода
'category': __('Configuration'),
# заголовок метода
'title': __("Configure a Package"),
# иконка для графической консоли
'image': 'calculate-core-setup,'
'preferences-desktop-default-applications',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-setup',
# права для запуска метода
'rights': ['setup_package'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClCoreSetupAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError,
setup_package.SetupPackageError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'merge', 'cl_verbose_set': "on"},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Configure a package"),
normal=('cl_core_pkg_name',),
expert=('cl_core_pkg_category',
'cl_core_pkg_version_opt',
'cl_core_pkg_slot_opt',
'cl_core_pkg_path',
'cl_core_arch_machine',
'cl_templates_locate',
'cl_core_pkg_system_set',
'cl_core_pkg_desktop_set',
'cl_core_pkg_root_set',
'cl_verbose_set',
'cl_dispatch_conf'),
next_label=_("Run"))]},
#
# Патч исходников пакета (cl-core-patch)
#
{
# идентификатор метода
'method_name': "core_patch",
# категория метода
'category': __('Configuration'),
# заголовок метода
'title': __("Patch"),
# иконка для графической консоли
'image': None,
# метода нет в графической консоли
'gui': False,
# консольная команда
'command': 'cl-core-patch',
# права для запуска метода
'rights': ['configure'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClCorePatchAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError,
setup_package.SetupPackageError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'patch',
'cl_protect_use_set!': 'off'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Configure a package"),
normal=('cl_core_pkg_name',),
expert=('cl_core_pkg_category',
'cl_core_pkg_version',
'cl_core_pkg_slot',
'cl_core_pkg_path',
'cl_core_arch_machine',
'cl_templates_locate',
'cl_verbose_set'),
next_label=_("Run"))]},
#
# Обновление конфигурационных файлов (cl-dispatch-conf)
#
{
# идентификатор метода
'method_name': "core_dispatch",
# категория метода
'category': __('Update '),
# заголовок метода
'title': __("Update Settings"),
# иконка для графической консоли
'image': 'calculate-core-dispatch,edit-find-replace,computer',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-dispatch-conf',
# права для запуска метода
'rights': ['configure'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClCoreDispatchAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError,
setup_package.SetupPackageError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'dispatch'},
# описание груп (список лямбда функций)
'groups': []},
#
# Отобразить сертификаты
#
{
# идентификатор метода
'method_name': "core_view_cert",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Show Certificates"),
# иконка для графической консоли
'image': 'calculate-core-view-cert,certificate-server,'
'application-certificate',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-view-cert',
# права для запуска метода
'rights': ['certificates'],
# объект содержащий модули для действия
'logic': {'Certificate': certificate.Certificate},
# описание действия
'action': ClCoreViewCert,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {
'cl_page_max!': lambda dv: len(dv.Get('cl_list_cert_id'))},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Certificates"),
normal=('cl_page_count', 'cl_page_offset'),
next_label=_("Next"))]},
#
# Отобразить детали сертификата
#
{
# идентификатор метода
'method_name': "core_detail_view_cert",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Certificate Details"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# права для запуска метода
'rights': ['certificates'],
# объект содержащий модули для действия
'logic': {},
# описание действия
'action': None,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Certificate details"),
normal=('cl_cert_id', 'cl_cert_groups',
'cl_cert_perms'),
custom_buttons=[('but0', _("Back"),
"core_view_cert",
"button")])]},
#
# Группы
#
{
# идентификатор метода
'method_name': "core_group_show",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Show Groups"),
# иконка для графической консоли
'image': 'calculate-core-group-show,user-group-properties,'
'view-certificate-import,application-certificate',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-group-show',
# права для запуска метода
'rights': ['core_group'],
# объект содержащий модули для действия
'logic': {'Groups': groups.Groups},
# описание действия
'action': ClCoreGroupShow,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {
'cl_page_max!': lambda dv: len(dv.Choice('cl_core_group'))},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Groups"),
normal=('cl_page_count', 'cl_page_offset'),
next_label=_("Next"))]},
#
# Отобразить детали группы
#
{
# идентификатор метода
'method_name': "core_detail_group",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Group Details"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# права для запуска метода
'rights': ['core_group'],
# объект содержащий модули для действия
'logic': {},
# описание действия
'action': None,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Group details"),
normal=(
'cl_core_group',
'cl_core_group_rights'),
custom_buttons=[('but0', _("Back"),
"core_group_show",
"button"),
('but1', _("Change"),
"core_group_mod",
"button"),
('but2', _("Delete"),
"core_group_del",
"button")])]},
#
# Изменить группу
#
{
# идентификатор метода
'method_name': "core_group_mod",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Modify Group"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-groupmod',
# права для запуска метода
'rights': ['core_group'],
# объект содержащий модули для действия
'logic': {'Groups': groups.Groups},
# описание действия
'action': ClCoreGroupMod,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'modify'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Modify group"),
normal=(
'cl_core_group',
'cl_core_group_rights'),
next_label=_("Done"),
custom_buttons=[('but2', _("Confirm"),
'core_change_group',
"button")])]},
#
# Добавить группу
#
{
# идентификатор метода
'method_name': "core_group_add",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Add a Group"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-groupadd',
# права для запуска метода
'rights': ['core_group'],
# объект содержащий модули для действия
'logic': {'Groups': groups.Groups},
# описание действия
'action': ClCoreGroupAdd,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'add'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Add a group"),
normal=(
'cl_core_group',
'cl_core_group_rights'),
next_label=_("Add"))]},
#
# Удалить группу
#
{
# идентификатор метода
'method_name': "core_group_del",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Delete the Group"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-groupdel',
# права для запуска метода
'rights': ['core_group'],
# объект содержащий модули для действия
'logic': {'Groups': groups.Groups},
# описание действия
'action': ClCoreGroupDel,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'delete'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Delete the group"),
normal=('cl_core_group',),
next_label=_("Delete"))]},
#
# Запрос на сертификат
#
{
# идентификатор метода
'method_name': "core_request_show",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Show Requests"),
# иконка для графической консоли
'image': 'calculate-core-request-show,view-certificate-import,'
'application-certificate',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-request-show',
# права для запуска метода
'rights': ['request'],
# объект содержащий модули для действия
'logic': {'Request': request.Request},
# описание действия
'action': ClCoreRequestShow,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {
'cl_page_max!': lambda dv: len(dv.Get('cl_list_req_id'))},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Show requests"),
normal=('cl_page_count', 'cl_page_offset'),
next_label=_("Next"))]},
#
# Отобразить детали запроса
#
{
# идентификатор метода
'method_name': "core_detail_request",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Request Details"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# права для запуска метода
'rights': ['request'],
# объект содержащий модули для действия
'logic': {},
# описание действия
'action': None,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Group details"),
normal=('cl_req_id', 'cl_req_user_name',
'cl_req_ip',
'cl_req_mac', 'cl_req_date',
'cl_req_location',
'cl_req_group'),
custom_buttons=[('but0', _("Back"),
"core_request_show",
"button"),
('but1', _("Confirm"),
"core_request_confirm",
"button"),
('but2', _("Delete"),
"core_request_del",
"button")])]},
#
# Удалить запрос
#
{
# идентификатор метода
'method_name': "core_request_del",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Delete the Request"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-request-del',
# права для запуска метода
'rights': ['request'],
# объект содержащий модули для действия
'logic': {'Request': request.Request},
# описание действия
'action': ClCoreRequestDel,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'delete'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Delete the request"),
normal=('cl_req_id',),
next_label=_("Delete"))]},
#
# Подтвердить запрос
#
{
# идентификатор метода
'method_name': "core_request_confirm",
# категория метода
# 'category':__('Utilities'),
# заголовок метода
'title': __("Confirm the Request"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-request-confirm',
# права для запуска метода
'rights': ['request'],
# объект содержащий модули для действия
'logic': {'Request': request.Request},
# описание действия
'action': ClCoreRequestConfirm,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'confirm'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Delete the request"),
normal=('cl_req_id', 'cl_req_group'),
next_label=_("Delete"))]},
#
# установить переменные
#
{
# идентификатор метода
'method_name': "core_variables",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Setup Variables"),
# иконка для графической консоли
'image': 'calculate-core-variables,applications-versioncontrol,'
'text-x-preview,text-x-makefile',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-variables',
# права для запуска метода
'rights': ['setup_variables'],
# объект содержащий модули для действия
'logic': {'Variables': set_vars.Variables},
# описание действия
'action': ClCoreVariables,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Setup variables"),
normal=('cl_variable_data',),
next_label=_("Save"))]},
#
# отобразить переменные
#
{
# идентификатор метода
'method_name': "core_variables_show",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("View Variables"),
# иконка для графической консоли
'image': None,
# метод в графической консоли
'gui': False,
# консольная команда
'command': 'cl-core-variables-show',
# права для запуска метода
'rights': ['configure'],
# объект содержащий модули для действия
'logic': {'Variables': set_vars.Variables},
# описание действия
'action': ClCoreVariablesShow,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Setup variables"),
normal=(
'cl_variable_filter',
'cl_variable_show'),
next_label=_("Show"))]},
#
# Выполнить настройку пакета (cl-config)
#
{
# идентификатор метода
'method_name': "core_config",
# категория метода
'category': __('Configuration'),
# заголовок метода
'title': __("Config"),
# иконка для графической консоли
'image': None,
# метода нет в графической консоли
'gui': False,
# консольная команда
'command': 'cl-config',
# права для запуска метода
'rights': ['configure'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClConfigAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError,
setup_package.SetupPackageError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'config', 'cl_verbose_set': "on"},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Configure a package"),
normal=('cl_core_pkg_name',),
expert=('cl_core_pkg_category',
'cl_core_pkg_version_opt',
'cl_core_pkg_slot_opt',
'cl_templates_locate',
'cl_verbose_set'),
next_label=_("Run"))]},
#
# отобразить переменные
#
{
# идентификатор метода
'method_name': "core_custom",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Custom Action"),
# иконка для графической консоли
'image': 'calculate-core-custom,gnome-desktop-config,desktop-config',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-custom',
# права для запуска метода
'rights': ['custom_configure'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClCoreCustomAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_verbose_set': "on", 'cl_human_edit_set': "on"},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Custom action"),
normal=(
'ac_custom_name', 'cl_human_edit_set',
'cl_verbose_set'),
expert=(
'ur_core_login', 'cl_core_arch_machine',
'cl_templates_locate',
'cl_dispatch_conf'),
next_label=_("Run"))]},
#
# перезапустить сервис calculate core
#
{
# идентификатор метода
'method_name': "core_restart",
# категория метода
'category': __('Utilities'),
# заголовок метода
'title': __("Restart calculate-core"),
# иконка для графической консоли
'image': 'calculate-core-restart,view-refresh',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-core-restart',
# права для запуска метода
'rights': ['core_restart'],
# объект содержащий модули для действия
'logic': {'UpdateConfigs': setup_package.UpdateConfigs},
# описание действия
'action': ClCoreRestartAction,
# объект переменных
'datavars': "core",
'native_error': (VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'restart'},
# описание груп (список лямбда функций)
'groups': []},
#
# создание резервной копии настроек
#
{
# идентификатор метода
'method_name': "backup",
# категория метода
'category':__('Backup'),
# заголовок метода
'title': __("Backup"),
# иконка для графической консоли
'image': 'calculate-backup',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-backup',
# права для запуска метода
'rights': ['backup'],
# объект содержащий модули для действия
'logic': {'Backup': Backup},
# описание действия
'action': ClBackupAction,
# объект переменных
'datavars': "core",
'native_error': (BackupError, VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': Actions.Backup},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("System backup"),
normal=('cl_backup_verbose_set',),
next_label=_("Run"))]},
#
# восстановление настроек из резервной копии
#
{
# идентификатор метода
'method_name': "backup_restore",
# категория метода
'category':__('Backup'),
# заголовок метода
'title': __("Restore"),
# иконка для графической консоли
'image': 'calculate-backup-restore',
# метод в графической консоли
'gui': True,
# консольная команда
'command': 'cl-backup-restore',
# права для запуска метода
'rights': ['backup'],
# объект содержащий модули для действия
'logic': {'Backup': Backup},
# описание действия
'action': ClBackupRestoreAction,
# объект переменных
'datavars': "core",
'native_error': (BackupError, VariableError, DataVarsError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': Actions.BackupRestore,
'core.cl_backup_action': Actions.Restore},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("System restore"),
normal=('cl_backup_verbose_set',),
brief=('cl_backup_file', 'cl_backup_time'),
next_label=_("Run"))],
'brief': {'next': __("Run"),
'name': __("System restore")}},
]
Loading…
Cancel
Save