You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-2.2-lib/pym/encrypt.py

233 lines
8.4 KiB

14 years ago
#-*- coding: utf-8 -*-
# Copyright 2008-2010 Calculate Ltd. http://www.calculate-linux.org
14 years ago
#
# 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
# для создания сертификата
import pwd
14 years ago
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, len=2):
14 years ago
"""Генерация соли для хеширования пароля (CRYPT)"""
chars = string.letters + string.digits + "./"
salt = ""
for i in range(len):
14 years ago
salt = salt + choice(chars)
return salt
def getHashPasswd(self, password, SecHashAlg):
"""Генерация хеша пароля,
Поддерживаемые алгоритмы шифрования пароля:
plain, md5, smd5, crypt, sha, ssha, lm, nt, shadow_ssha512,
shadow_ssha256, shadow_md5
14 years ago
"""
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 == "shadow_ssha512":
salt = self.__GenCryptSalt__(8)
hashPwd = crypt.crypt(password, "$6$%s$"%salt)
elif SecHashAlg == "shadow_ssha256":
salt = self.__GenCryptSalt__(8)
hashPwd = crypt.crypt(password, "$5$%s$"%salt)
elif SecHashAlg == "shadow_md5":
salt = self.__GenCryptSalt__(8)
hashPwd = crypt.crypt(password, "$1$%s$"%salt)
14 years ago
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
14 years ago
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",
14 years ago
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)
# получаем id и gid пользователя
try:
pwdObj = pwd.getpwnam(userName)
except:
self.printERROR(_("Not found user %s")%userName)
14 years ago
return False
uid = pwdObj.pw_uid
gid = pwdObj.pw_gid
14 years ago
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._createDir(0, 0, dirName, 0755)
14 years ago
# Создание конфигурационного файла
self._createFile(cnfFile, textCnf, 0, 0, 0600)
14 years ago
# Создание сертификата
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 is False:
14 years ago
self.printERROR(_("Can not create certificate %s")%certFile)
return False
# Проверка сертификата
textLine = execProg("%s x509 -subject -fingerprint -noout -in %s"\
%(sslFile, certFile))
if textLine is False:
14 years ago
self.printERROR(_("Can not create certificate %s")%certFile)
return False
return True
def _createDir(self, uid, gid, dirName, mode=0700):
"""Создание пользовательской директории"""
if not os.path.exists(dirName):
os.makedirs(dirName)
if mode:
os.chmod(dirName,mode)
os.chown(dirName,uid,gid)
return True
else:
self.printERROR(_("Path %s exists") %dirName)
return False
def _createFile(self, fileName, fileTxt, uid, gid, mode=0644):
"""Создает пользовательский файл с содержимым
Если директория файла не существует то ошибка
"""
dirName = os.path.split(fileName)[0]
if not os.path.exists(dirName):
self.printERROR(_("Path %s not exists") %dirName)
return False
fd = os.open(fileName, os.O_CREAT)
os.close(fd)
os.chmod(fileName, mode)
os.chown(fileName,uid,gid)
if fileTxt:
FD = open(fileName, "r+")
FD.write(fileTxt)
FD.close()
return True