diff --git a/pym/cl_datavars.py b/pym/cl_datavars.py new file mode 100644 index 0000000..368670b --- /dev/null +++ b/pym/cl_datavars.py @@ -0,0 +1,589 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate Ltd. 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 cl_utils +from cl_lang import lang +from cl_template import iniParser +from cl_string import columnWrite + +# Перевод модуля на другой язык +tr = lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) + +class var: + '''Объект "Переменная окружения"''' + # название сервиса которому принадлежит переменная + #(Global, Builder, Client, Server итд) + service = None + # значение переменной + value = "" + # режим записи (атрибут mode) + mode = "r" + # переменная для внутреннего использования (official) + official = False + # количество вызовов метода заполнения + countFill = 0 + # объект в котором создан этот объект + parentObj = None + # запускать или нет метод заполнения + fillStart = True + # dynamic = True то переменная динамическая при повтороном запуске + # запускается метод заполнения + # метод заполнения не запускается только если fillStart = False + # (осторожно возможно зацикливание программы если методы заполнения + # переменных используют методы друг друга) + dynamic = False + + def __init__(self, parentObj): + # словарь зависимых переменных {имя:значение} + self.dependValues = {} + # тип переменной (атрибут type) + self.type = ('default') + # список допустимых значений переменных (select) + self.select = () + # объект который создал этот объект + self.parentObj = parentObj + + def is_update(self): + #Нужно ли перезапускать метод заполнения (если зависимые переменные + #обновились то нужно) + upd = False + for depVarName in self.dependValues.keys(): + value = self.parentObj.__getattribute__(depVarName).Get() + if self.dependValues[depVarName] != value: + self.dependValues[depVarName] =\ + self.parentObj.__getattribute__(depVarName).value + upd = True + break + return upd + + def Get(self): + """Получение значения переменной""" + if not self.fillStart: + return self.value + if self.dynamic: + self.value = self.Fill() + return self.value + if not self.value: + if self.countFill>0: + return self.value + self.countFill += 1 + self.value = self.Fill() + if self.dependValues and self.is_update(): + self.countFill += 1 + self.value = self.Fill() + return self.value + + def Set(self, value): + """Запись значения переменной""" + self.value = value + return self.value + + def Fill(self): + """Заполнение переменной в далнейшем заменяем методом заполнения""" + return self.value + + +class DataVars(object): + class DataVarsError(Exception): + """Класс ошибок""" + pass + + # Импортируемые модули - (раздел: модуль переменных, модуль заполнения + #переменных) + __modlist={'Global':('cl_vars','cl_fill')} + def __init__(self): + # Для нахождения зависимостей переменных + self.__levelNumber = 0 + self.__LevelsVar = [] + # Для хранения импортированных модулей и объектов + #[(cекция,импортированный модуль переменных, объект заполнения),] + self._importList = [] + self.importData("Global") + + def importData(self, section, modlist=[]): + """Импортирует модули с переменными и модули с функциями заполнения + + section секция раздела (Global, Server, Client итд) + создает необходимые структуры данных + """ + if modlist: + self.__modlist.update({section:modlist}) + if not section in self.__modlist.keys(): + raise self.DataVarsError(_("Unsupported section %s")%section) + modVar = self.__modlist[section][0] + modFill = self.__modlist[section][1] + # Импортируем класс описания переменных и класс заполнения + try: + globals()[modVar] = __import__(modVar) + except (ImportError, AttributeError), e: + err1 = _("Error in import module %s")%modVar + err2 = _("error") + ": " +str(e) + raise self.DataVarsError("%s\n%s"%(err1,err2)) + + flagFindFillModule = True + try: + globals()[modFill] = __import__(modFill) + except (ImportError, AttributeError), e: + if "No module named" in str(e): + flagFindFillModule = False + else: + err1 = _("Error in import module %s")%modFill + err2 = _("error") + ": " +str(e) + raise self.DataVarsError("%s\n%s"%(err1,err2)) + + if flagFindFillModule: + # Создаем объект с методами заполнения переменных + fillObj = globals()[modFill].fillVars() + # Подключаем методы получения и записи переменных + fillObj.Get = self.Get + fillObj.Set = self.Set + else: + fillObj = False + # Заполняем self._importList + self._importList.insert(0,(section,globals()[modVar],fillObj)) + + def __findVarData(self, nameVar): + """Находит данные для создания объекта переменная в модулях и + + объектах + """ + # Ищем переменную в модуле + dataVar = False + e = False + for section, moduleVar, fillobj in self._importList: + try: + dataVar = getattr(moduleVar.Data, nameVar) + except AttributeError, e: + pass + if dataVar: + break + if dataVar == False: + err1 = _("Not found variable %s")%nameVar + err2 = "" + if e: + err2 = _("error") + ": " +str(e) + raise self.DataVarsError("%s\n%s"%(err1,err2)) + dataVar['service'] = section + # Ищем метод в объекте методов заполнения + nameMethod = "get_" + nameVar + flagFindMetod = False + for section, moduleVar, fillobj in self._importList: + if fillobj and hasattr(fillobj, nameMethod): + flagFindMetod = True + method = fillobj.__getattribute__(nameMethod) + break + if flagFindMetod: + return (dataVar,method) + else: + return (dataVar,False) + + def __setAttributesVar(self, var ,nameVar, dict): + """Установка аттрибутов для созданного объекта var + + название аттрибута и его значение берется из словаря dict + """ + dict['type'] = nameVar.split('_') + if not set(dict.keys()) <= set(dir(var)): + raise self.DataVarsError(\ + _("error initalize variable %s, incorrect data")%nameVar) + for nameAttr in dict.keys(): + setattr(var,nameAttr, dict[nameAttr]) + return True + + def __Get(self, nameVar): + ret = "" + self.__LevelsVar.append((self.__levelNumber, nameVar)) + self.__levelNumber += 1 + #nameMethod = "get_" + nameVar + if self.__dict__.has_key(nameVar): + ret = self.__getattribute__(nameVar).Get() + elif self.__findVarData(nameVar): + dictVar, methodFill =self.__findVarData(nameVar) + varobj = var(self) + # Устанавливаем аттрибуты + self.__setAttributesVar(varobj, nameVar, dictVar) + if methodFill: + varobj.Fill = methodFill + self.__setattr__(nameVar, varobj) + ret = self.__getattribute__(nameVar).Get() + self.__levelNumber -= 1 + if self.__levelNumber == 0 and\ + self.__getattribute__(nameVar).fillStart and\ + len(self.__LevelsVar)>1: + links = self.__getLinks(self.__LevelsVar) + for name in links.keys(): + for nameLink in links[name].keys(): + val = self.__getattribute__(nameLink).Get() + self.__getattribute__(name).dependValues[nameLink] = val + if self.__levelNumber == 0: + self.__LevelsVar = [] + return ret + + def Get(self, nameVar): + return self.__Get(nameVar) + + + def __Set(self, nameVar, value, force=False): + nameMethod = "get_" +nameVar + if not self.__dict__.has_key(nameVar) and self.__findVarData(nameVar): + dictVar, methodFill =self.__findVarData(nameVar) + varobj = var(self) + # Устанавливаем аттрибуты + self.__setAttributesVar(varobj, nameVar, dictVar) + if methodFill: + varobj.Fill = methodFill + self.__setattr__(nameVar, varobj) + if self.__dict__.has_key(nameVar): + if not force and "r" in getattr(self, nameVar).mode: + print _("Attempt to rewrite a variable for reading:%s")\ + %nameVar + return False + self.__getattribute__(nameVar).fillStart = False + return self.__getattribute__(nameVar).Set(value) + + def Set(self, nameVar, value, force=False): + return self.__Set(nameVar, value, force) + + def __frame(self, lVar): + """получить список областей зависимости переменных""" + data = [] + if not lVar: + return data + firstLevel = lVar[0][0] + for level, name in lVar[1:]: + if level> firstLevel: + data.append((level, name)) + else: + break + return data + + def __getLinks(self, lVar): + """Получить список переменных и от каких переменных они зависят + + на вход список [(уровень рекурсии, название переменной),] + """ + links = {} + frames = {} + levelLinks = {} + lVarFr = lVar + for level, name in lVar: + fr = self.__frame(lVarFr) + if not frames.has_key(name): + frames[name] = fr + levelLinks[name] = level+1 + lVarFr = lVarFr[1:] + for name in frames.keys(): + level = levelLinks[name] + fr = frames[name] + links[name] = {} + for lv, nm in fr: + if level == lv: + links[name][nm] = "" + return links + + def __getPathCalculateIni(self): + """Получить пути до ini файлов""" + return self.Get('cl_env_path') + + def __getSection(self, vname): + """секция для записи в ini файл переменной + + vname - имя переменной + """ + if self.__dict__.has_key(vname): + if self.__dict__[vname].service == 'Global': + return 'calculate' + else: + return self.__dict__[vname].service.lower() + + def __writeVarValue(self, vname, val, location, header): + '''Записать значение в calculate.ini + + Параметры: + vname имя переменной + val значение переменной + location расположение ini файла ('default', 'local', 'remote') + header раздел ini файла ('client', 'server', 'calculate') + + Возвращаемые значение: + True запись успешна + False запись не удалсь + ''' + # получаем все пути до ini файлов + calculate_ini = self.__getPathCalculateIni() + # получаем полный путь до файла ini + if location == 'default': + name_calculate_ini = calculate_ini[2] + elif location == 'local': + name_calculate_ini = calculate_ini[1] + elif location == 'remote': + name_calculate_ini = calculate_ini[0] + else: + return False + # извлекаем из полного имени файла путь + onlydir = os.path.split(name_calculate_ini)[0] + try: + # проверяем чтобы путь до ини файла существовал + if not os.path.exists(onlydir): + # создаем его если отсутствует + os.makedirs(onlydir) + except OSError (nerr,msg): + print nerr, msg + return False + config = iniParser(name_calculate_ini) + # Получаем секцию конфигурационного файла + if not header: + header = self.__getSection(vname) + return config.setVar(header,{vname: cl_utils.convertStrListDict(val)}) + + def __deleteVarValue(self, vname, location, header): + '''Удалить переменную в calculate.ini + + Параметры: + vname имя переменной + location расположение ini файла ('default', 'local', 'remote') + + Возвращаемые значение: + True удалено успешна + False удаление не удалсь + ''' + # получаем все пути до ini файлов + calculate_ini = self.__getPathCalculateIni() + # получаем полный путь до файла ini + if location == 'default': + name_calculate_ini = calculate_ini[2] + elif location == 'local': + name_calculate_ini = calculate_ini[1] + elif location == 'remote': + name_calculate_ini = calculate_ini[0] + else: + return False + # извлекаем из полного имени файла путь + onlydir = os.path.split(name_calculate_ini)[0] + # проверяем чтобы путь до ини файла существовал + if not os.path.exists(onlydir): + return False + config = iniParser(name_calculate_ini) + # Получаем секцию конфигурационного файла + if not header: + header = self.__getSection(vname) + # Удаляем переменную + retDelVar = config.delVar(header, vname) + retDelArea = True + if not config.getAreaVars(header): + retDelArea = config.delArea(header) + if retDelArea and retDelVar: + return True + else: + return False + + def Write(self, vname, val, force=False, location='default',header=False): + '''Установить и записать значение переменной в ini файл + + Параметры: + vname имя переменной + val значение переменной + force "принудительный режим" + location расположение ini файла ('default', 'local', 'remote') + header раздел ini файла ('client', 'server', 'calculate') + ''' + if self.__Set(vname, val, force)!= False: + if not val.strip(): + self.__deleteVarValue(vname, location, header) + self.__writeVarValue(vname, val, location, header) + return True + return False + + def Delete(self, vname, location='default', header=False): + '''Удалить переменную в calculate.ini + + Параметры: + vname имя переменной + location расположение ini файла ('default', 'local', 'remote') + + Возвращаемые значение: + True удалено успешна + False удаление не удалсь + ''' + return self.__deleteVarValue(vname, location, header) + + def __getActiveSections(self): + """активные секции в ini файле""" + act_section = [] + for service,t,t in self._importList: + if service == "Global": + act_section.append('calculate') + else: + act_section.append(service.lower()) + return act_section + + def flIniFile(self): + '''Заместить значение переменных значениями из ини файлов + + Возвращаемые значения: + cловарь импортированных переменных - переменные считаны + False - файл не был обнаружен + ''' + #Cловарь переменных из ini файлов + importVars = {} + calculate_ini = self.__getPathCalculateIni() + # активные секции (секции из которых будут использованы переменные) + act_section = self.__getActiveSections() + set_act_section = set(act_section) + i = 0 + locations = ['remote','local','default'] + for name_calculate_ini in calculate_ini: + # проверить сущестование ini файла + if os.path.exists(name_calculate_ini): + # получить объект настроенный на ini + config = iniParser(name_calculate_ini) + # получаем все секции из конфигурационного файла + allsect = config.getAllSectionNames() + if not allsect: + continue + # находим встречающиеся у обоих секции + act_sect = tuple(set(allsect)& set_act_section) + # словарь переменных для ini - файла + importFileVars = {} + # получаем все переменные из всех секций + for section in act_sect: + allvars = config.getAreaVars(section) + if allvars == False: + return False + # словарь переменных для ini - файла + importFileVars = {} + # принудительно переписать все переменные окружения + # полученные из ini + for (k,v) in allvars.items(): + k = k.encode("UTF-8") + value = cl_utils.convertStrListDict(v.encode("UTF-8")) + self.Set(k, value, True) + importFileVars[k] = value + if i < 3: + importVars[locations[i]] = importFileVars + i += 1 + return importVars + + + #def defined(self, vname): + #if vname: + #if self.__dict__.has_key(vname): + #return True + #return False + def defined(self, vname): + return True + + + + def exists(self, nameVar): + """ Определяет существует ли переменная с таким имененм + """ + if self.__dict__.has_key(nameVar): + return True + foundVar = False + # Ищем переменную в импортируемых модулях + for section, moduleVar, fillobj in self._importList: + if moduleVar.Data.__dict__.has_key(nameVar): + foundVar = True + break + return foundVar + + def getVars(self, type_names=None): + ret = {} + for section, moduleVar, fillobj in self._importList: + dataVar=moduleVar.Data + dictVars = dir(dataVar) + for nameVar in dictVars: + if not "__" in nameVar: + if not (getattr(dataVar,nameVar).has_key("official") and\ + getattr(dataVar,nameVar)['official']): + self.Get(nameVar) + if type_names: + #type_names.sort() + varType =list(getattr(dataVar,nameVar)['type']) + #varType.sort() + #print type_names + #print varType + #print + if not set(type_names)<=set(varType): + continue + ret[nameVar] = getattr(self,nameVar) + return ret + + #распечатать список переменных с значениями + def printVars(self,type_names=None): + var=None + var=self.getVars(type_names) + mlen_name=0; + mlen_type=0; + mlen_mode=0; + for i,j in var.items(): + if len(i)>mlen_name: + mlen_name=len(i) + #if len(str(j.type))>mlen_type: + #mlen_type=len(str(j.type)) + vtype=str(type(var[i].value)).split(" ")[1][1] + if not '[' in var[i].mode: + if vtype in ['d','l']: + mode="[%s%s]"%(var[i].mode.lower(),vtype) + else: + mode="[%s]"%(var[i].mode.lower()) + var[i].mode=mode + if len(mode)>mlen_mode: + mlen_mode=len(mode) + plist=var.keys() + plist.sort() + br = cl_utils.fillstr("-",mlen_name) + " " +\ + cl_utils.fillstr("-",mlen_mode) + " " + cl_utils.fillstr("-",10) + #cl_utils.fillstr("-",mlen_type) + " " +\ + + print "The list of variables:" + print "var name".center(mlen_name),\ + "Mode","Value" + #"Type".center(mlen_type),\ + + + print br + for i in plist: + #if var[i].value is None: + #continue + p_val=var[i].value + if var[i].official: + continue + columnWrite( i, mlen_name, var[i].mode.lower(), + mlen_mode, + #str(var[i].type), + #mlen_type, + p_val) + print br + +class glob_attr: + """Глобальные аттрибуты для методов заполнения переменных""" + + def _runos(self,cmd, ret_first=None, env={}): + """Вернуть результат выполнения команды ОС""" + if not env: + envDict = {} + env.update(os.environ.items() + [("PATH",cl_utils.getpathenv())] +\ + env.items()) + retCode, programOut = cl_utils.runOsCommand(cmd, None, ret_first, env) + if not retCode: + return programOut + return False diff --git a/pym/cl_opt.py b/pym/cl_opt.py new file mode 100644 index 0000000..02ead56 --- /dev/null +++ b/pym/cl_opt.py @@ -0,0 +1,201 @@ +#-*- coding: utf-8 -*- + +# Copyright 2010 Mir Calculate Ltd. 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 optparse +import sys +import re + +from cl_lang import lang +tr = lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) +optparse._ = _ + +def make_option(shortOption=None,longOption=None, + optVal=None, help=None, default=None, + action=None, type=None, choices=None): + """Make option. Used for processing options parameter in opt __init__. + + shortOption short option + longOption long option + optVal argument name, if specified then + option is store, else bool value + help help string + default default value of this option + action another action (at example append, for creating list) + type type of value + choices choice values for type 'choice' + + Examples: + Simple bool option: + make_option(shortOption="q",help=_("quiet work mode")) + + Simple value option: + make_option(longOption="file",help=_("log file"),optVal="LOGFILE", + default="/var/log/test.log") + + Choice option: + make_option(shortOption="color",help=_("color mode"), type="choice", + choices=["auto","always","never"]) + + Many option: + make_option(longOption="set",help=_("set variable"),action="append", + optVal="VAR") + """ + # create option by arguments + args = [] + dest = None + if not shortOption is None: + args.append("-%s"%shortOption) + dest = shortOption + if not longOption is None: + args.append("--%s"%longOption) + if type == "choice": + action = "store" + else: + if not optVal is None: + if not action: + action = "store" + type = "string" + else: + if not action: + action = "store_true" + default = False + type = None + return optparse.make_option(*args, action=action, type=type, + dest=dest, metavar=optVal, + help=help, default=default, + choices=choices) + +class opt(optparse.OptionParser): + """Class of options for calculate utilities + + Example: + class new_utility(opt): + def __init__(self): + opt.__init__(self, + package=__app__, + version=__version__, + description=_("Some description"),\ + option_list= [\ + #Simple bool option: + { + 'shortOption':'q', + 'help':_("quiet work mode") + }, + #Simple value option: + { + 'longOption':"file", + 'help':_("log file"), + 'optVal':"LOGFILE", + "default":"/var/log/test.log") + }, + #Choice option: + { + 'shortOption':"color", + 'help':_("color mode"), + 'type':"choice", + 'choices'=["auto","always","never"] + }, + #Summary option: + { + 'longOption':"set", + 'help':_("set variable"), + 'action':"append", + 'optVal'="VAR" + } + ] + ) + """ + + variable_control = \ + [{'longOption':"set", + 'optVal':"VAR=VALUE", + 'action':'append', + 'help':_("set value for variable (comma - delimeter)") + }, + {'longOption':"vars", + 'optVal':"TYPE_VAR", + 'help':_("print variables") + " (TYPE_VAR - all: " + \ + _("full variables list") +")" + }] + + color_control = \ + [ + {'longOption':"color", + 'optVal':"WHEN", + 'type':'choice', + 'choices':['never','always','auto'], + 'help':_("control whether color is used. WHEN may be") +\ + " 'never', 'always', "+ _("or") + " 'auto'" + }] + + def __init__(self, + usage=None, + option_list=None, + option_class=optparse.Option, + version=None, + conflict_handler="error", + description=None, + formatter=None, + add_help_option=True, + prog=None, + epilog=None, + package=None): + self.package = package + optparse.OptionParser.__init__(self, + usage=usage, + option_list=[make_option(**i) for i in option_list], + option_class=option_class, + version=version, + conflict_handler=conflict_handler, + description=description, + formatter=formatter, + add_help_option=add_help_option, + prog=prog, + epilog=epilog) + self.formatter._long_opt_fmt = "%s %s" + + def get_usage(self): + """Replace standard help header""" + if self.usage: + return "%s %s\n\n%s"%(self.package,self.version, + self.formatter.format_usage(self.expand_prog_name(self.usage))) + else: + return "" + + def format_help(self, formatter=None): + """Decode format help from utf-8 to unicode""" + return \ + optparse.OptionParser.format_help(self,formatter).decode('UTF-8') + + def error(self, msg): + """error(msg : string) + + Print a usage message incorporating 'msg' to stderr and exit. + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(sys.stderr) + self.exit(2, "%s: %s: %s\n" % (self.get_prog_name(), _("error"), msg)) + + def checkVarSyntax(self,values): + """Check value of parameter set, was used for change vars""" + reCheckSet = re.compile("^([a-z_]+=[^,]+)(,\s*[a-z_]+=[^,]+)*$") + if values.set: + for val in values.set: + if not reCheckSet.match(val): + self.error(_("wrong variable set %s")%val) diff --git a/pym/encrypt.py b/pym/encrypt.py new file mode 100644 index 0000000..464763a --- /dev/null +++ b/pym/encrypt.py @@ -0,0 +1,186 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate Ltd. 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 hashlib +import crypt +import string +import time +from random import choice +from base64 import encodestring as b64encode +import smbpasswd +from cl_print import color_print +# для создания сертификата +from server.users import users +from server.utils import execProg +import cl_lang +# Перевод модуля +tr = cl_lang.lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) + +class encrypt(color_print): + """Класс хранения общих методов используемых для настройки сервисов + + Методы шифрования, создания сертификатов и.т. д + """ + + def __GenCryptSalt__(self): + """Генерация соли для хеширования пароля (CRYPT)""" + chars = string.letters + string.digits + "./" + salt = "" + for i in range(2): + salt = salt + choice(chars) + return salt + + def getHashPasswd(self, password, SecHashAlg): + """Генерация хеша пароля, + + Поддерживаемые алгоритмы шифрования пароля: + plain, md5, smd5, crypt, sha, ssha, lm, nt + """ + if not password: + self.printERROR(_("ERROR") + " getHashPasswd: " +\ + _("password empty")) + return False + + hashPwd = "" + if SecHashAlg == "plain": + hashPwd = password + + elif SecHashAlg == "md5": + h = hashlib.md5(password) + hashPwd = "{MD5}" + b64encode(h.digest()) + + elif SecHashAlg == "smd5": + salt = os.urandom(4) + h = hashlib.md5(password) + h.update(salt) + hashPwd = "{SMD5}" + b64encode(h.digest() + salt) + + elif SecHashAlg == "crypt": + salt = self.__GenCryptSalt__() + hashPwd = "{CRYPT}" + crypt.crypt(password, salt) + + elif SecHashAlg == "sha": + h = hashlib.sha1(password) + hashPwd = "{SHA}" + b64encode(h.digest()) + + elif SecHashAlg == "ssha": + salt = os.urandom(4) + h = hashlib.sha1(password) + h.update(salt) + hashPwd = "{SSHA}" + b64encode(h.digest() + salt) + + elif SecHashAlg == "lm": + hashPwd = smbpasswd.lmhash(password) + + elif SecHashAlg == "nt": + hashPwd = smbpasswd.nthash(password) + + else: + self.printERROR(_("ERROR") + " getHashPasswd: " +\ + _("Can not support '%s' crypto algorithm")\ + %SecHashAlg) + return False + return hashPwd + + def createCertificate(self, sslCountry="US", + sslState="California", + sslLocality="Santa Barbara", + sslOrganization="SSL Server", + sslUnit="For Testing Purposes Only", + sslCommonName="localhost", + sslEmail="root@localhost", + nsCertType="server", + sslDays=730, + sslBits=1024, + userName="root",groupName="root", + certFile="/tmp/server.pem", + certFileMode=0400, + keyFile="/tmp/server.key", + keyFileMode=0400): + """Создает сертификат""" + certAndKeyFiles = [certFile, keyFile] + foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles) + if len(foundCertFiles)==2: + return True + # Удаляем файл сертификата + map(lambda x: os.remove(x), foundCertFiles) + # Объект для работы с пользователями + usersObj = users() + # получаем id и gid пользователя + uidAndGid = usersObj.getUserUidAndGid(userName, groupName) + if not uidAndGid: + return False + uid, gid = uidAndGid + textCnf="""[ req ] +prompt = no +default_bits = %s +distinguished_name = req_dn + +[ req_dn ] +C = %s +ST = %s +L = %s +O = %s +OU = %s +CN = %s +emailAddress = %s + +[ cert_type ] +nsCertType = %s +"""%(sslBits, sslCountry, sslState, sslLocality, sslOrganization, sslUnit, + sslCommonName, sslEmail, nsCertType) + # генерируем название файла конфигурации + strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time())) + cnfFile = "/tmp/%s.cnf" %strData + sslFile = "/usr/bin/openssl" + if not os.path.exists(sslFile): + self.printERROR(_("Can not found %s")%sslFile) + return False + # Cоздание директорий + for fileName in certAndKeyFiles: + dirName = os.path.split(fileName)[0] + if not os.path.exists(dirName): + self.createUserDir(0, 0, dirName, 0755) + # Создание конфигурационного файла + usersObj.createUserFile(cnfFile, textCnf, 0, 0, 0600) + # Создание сертификата + textLine = execProg(\ + "%s req -new -x509 -nodes -config %s -days %s -out %s -keyout %s"\ + %(sslFile, cnfFile, sslDays, certFile, keyFile)) + # Удаление конфигурационного файла + if os.path.exists(cnfFile): + os.remove(cnfFile) + # Меняем права + if os.path.exists(certFile): + os.chown(certFile, uid,gid) + os.chmod(certFile, certFileMode) + if os.path.exists(keyFile): + os.chown(keyFile, uid,gid) + os.chmod(keyFile, keyFileMode) + if textLine == False: + self.printERROR(_("Can not create certificate %s")%certFile) + return False + # Проверка сертификата + textLine = execProg("%s x509 -subject -fingerprint -noout -in %s"\ + %(sslFile, certFile)) + if textLine == False: + self.printERROR(_("Can not create certificate %s")%certFile) + return False + return True