Added method created CA signed certificates.

develop
Самоукин Алексей 14 years ago
parent 0120fe0a65
commit 648a4fa4cc

@ -33,6 +33,8 @@ import pwd
from server.utils import execProg
import cl_overriding
import cl_lang
from cl_utils import genpassword, removeDir
# Перевод модуля
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
@ -60,7 +62,7 @@ class encrypt(color_print):
shadow_ssha256, shadow_md5
"""
if not password:
self.printERROR(_("ERROR") + " getHashPasswd: " +\
self.printERROR(_("ERROR") + " getHashPasswd: " +
_("password empty"))
return False
@ -110,32 +112,403 @@ class encrypt(color_print):
hashPwd = nthash(password)
else:
if SecHashAlg in ("lm","nt"):
self.printERROR(_("ERROR") + " getHashPasswd: " +\
(_("Can not support '%s' crypto algorithm")\
self.printERROR(_("ERROR") + " getHashPasswd: " +
(_("Can not support '%s' crypto algorithm")
%SecHashAlg) + " " + _("without py-smbpasswd"))
else:
self.printERROR(_("ERROR") + " getHashPasswd: " +\
_("Can not support '%s' crypto algorithm")\
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",
certFile="/tmp/server.pem",
certFileMode=0400,
keyFile="/tmp/server.key",
keyFileMode=0400):
class certificate(color_print):
sslCountry = "RU"
sslState = "Saint-Petersburg"
sslLocality = "Saint-Petersburg"
sslOrganization = "Calculate Ltd."
sslUnit = "SSL"
sslCommonName = "localhost"
sslEmail = "support@calculate.ru"
nsCertType = "server"
sslDays = 3653
sslBits = 1024
userName = "root"
fileMode = 0400
certsDir = "/var/calculate/ssl"
tmpDir = os.path.join(certsDir,"tmp")
certFile = os.path.join(tmpDir, "server.crt")
keyFile = os.path.join(tmpDir, "server.key")
csrFile = os.path.join(tmpDir, "server.csr")
CAPath = os.path.join(certsDir,"main")
CACertFileName = "CA.crt"
CAKeyFileName = "CA.key"
CACrlFileName = "CA.crl"
rCACertPath = "crt"
rCAKeyPath = "key"
rCACrlPath = "crl"
rSerialFileName = "serial"
rDatabaseFileName = "index.dat"
sslFile = "/usr/bin/openssl"
templCnfCA = """[ ca ]
default_ca = CA_default
[ CA_default ]
dir = %(CAPath)s
certs = $dir/%(rCACertPath)s
crl_dir = $dir/%(rCACrlPath)s
database = $dir/%(rDatabaseFileName)s
new_certs_dir = $dir/%(rCACertPath)s
certificate = $dir/%(rCACertFile)s
serial = $dir/%(rSerialFileName)s
crlnumber = $dir/crlnumber
crl = $dir/%(rCACrlFile)s
private_key = $dir/%(rCAKeyFile)s
RANDFILE = $dir/%(rRandFile)s
x509_extensions = usr_cert
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days= 30
default_md = default
preserve = no
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ usr_cert ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ req ]
prompt = no
default_bits = %(sslBits)s
x509_extensions = v3_ca
string_mask = utf8only
distinguished_name = req_dn
[ req_dn ]
C = %(sslCountry)s
ST = %(sslState)s
L = %(sslLocality)s
O = %(sslOrganization)s
OU = %(sslUnit)s
CN = %(sslCommonName)s
emailAddress = %(sslEmail)s
[ cert_type ]
nsCertType = %(nsCertType)s
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
"""
templCnfData = """[ req ]
prompt = no
default_bits = %(sslBits)s
distinguished_name = req_dn
[ req_dn ]
C = %(sslCountry)s
ST = %(sslState)s
L = %(sslLocality)s
O = %(sslOrganization)s
OU = %(sslUnit)s
CN = %(sslCommonName)s
emailAddress = %(sslEmail)s
[ cert_type ]
nsCertType = %(nsCertType)s
"""
templCreateKey = "%(sslFile)s genrsa -out %(certKeyFile)s %(sslBits)s"
templCreateCert = "%(sslFile)s req -new -x509 -days %(sslDays)s "\
"-config %(cnfFile)s -key %(certKeyFile)s "\
"-out %(certFile)s"
templCreateReq = "%(sslFile)s req -new -days %(sslDays)s "\
"-config %(cnfFile)s -key %(certKeyFile)s "\
"-out %(certCsrFile)s"
templCreateSignCert = "%(sslFile)s ca -batch -config %(cnfFile)s "\
"-policy policy_anything -days %(sslDays)s "\
"-out %(certFile)s -infiles %(certCsrFile)s"
def createCnfFile(self, textCnf):
'''Generate openssl.cnf file'''
if not os.path.exists(self.sslFile):
self.printERROR(_("Can not found %s")%self.sslFile)
return False
strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time()))
cnfFileName = "%s.%s.cnf" %(strData,genpassword())
if not os.path.exists(self.tmpDir):
self._createDir(self.tmpDir)
cnfFile = os.path.join(self.tmpDir,cnfFileName)
self._createFile(cnfFile, textCnf)
return cnfFile
def checkCertificate(self, certFile):
# Проверка сертификата
textLine = execProg("%s x509 -subject -fingerprint -noout -in %s"
%(self.sslFile, certFile))
if textLine is False:
self.printERROR(_("Error checking certificate %s")%certFile)
return False
return True
def createCertificateAutority(self,sslCountry=sslCountry,
sslState=sslState,
sslLocality=sslLocality,
sslOrganization=sslOrganization,
sslUnit=sslUnit,
sslCommonName=sslCommonName,
sslEmail=sslEmail,
nsCertType=nsCertType,
sslDays=sslDays,
sslBits=sslBits,
userName=userName,
CAPath=CAPath,
CACertFileName=CACertFileName,
CAKeyFileName=CAKeyFileName,
CACrlFileName=CACrlFileName,
fileMode=fileMode,
force=False):
'''Create CA'''
rCACertFile = os.path.join(self.rCACertPath, CACertFileName)
rCAKeyFile = os.path.join(self.rCAKeyPath, CAKeyFileName)
rCACrlFile = os.path.join(self.rCACrlPath, CACrlFileName)
rRandFile = os.path.join(self.rCAKeyPath,".rnd")
CACertFile = os.path.join(CAPath, rCACertFile)
CAKeyFile = os.path.join(CAPath, rCAKeyFile)
# Cerificates exists
if not force and os.path.isfile(CACertFile) and\
os.path.isfile(CAKeyFile):
return True
# получаем id и gid пользователя
try:
pwdObj = pwd.getpwnam(userName)
except:
self.printERROR(_("Not found user %s")%userName)
return False
uid = pwdObj.pw_uid
gid = pwdObj.pw_gid
# delete certificate dir
if os.path.isdir(CAPath):
removeDir(CAPath)
# create certificate dirs
self._createDir(CAPath)
CACertPath = os.path.join(CAPath, self.rCACertPath)
CAKeyPath = os.path.join(CAPath, self.rCAKeyPath)
CACrlPath = os.path.join(CAPath, self.rCACrlPath)
for createDir in [CACertPath, CAKeyPath, CACrlPath]:
self._createDir(createDir)
# save serial number
SerialFile = os.path.join(CAPath, self.rSerialFileName)
self._createFile(SerialFile, "01\n")
# create database file
DatabaseFile = os.path.join(CAPath, self.rDatabaseFileName)
self._createFile(DatabaseFile, "")
textCnf = self.templCnfCA%{'CAPath':CAPath,
'rCACertPath':self.rCACertPath,
'rCACrlPath':self.rCACrlPath,
'rDatabaseFileName':self.rDatabaseFileName,
'rCACertFile':rCACertFile,
'rSerialFileName':self.rSerialFileName,
'rCACrlFile':rCACrlFile,
'rCAKeyFile':rCAKeyFile,
'rRandFile':rRandFile,
'sslBits':sslBits,
'sslCountry':sslCountry,
'sslState':sslState,
'sslLocality':sslLocality,
'sslOrganization':sslOrganization,
'sslUnit':sslUnit,
'sslCommonName':sslCommonName,
'sslEmail':sslEmail,
'nsCertType':nsCertType}
cnfFile = self.createCnfFile(textCnf)
if cnfFile is False:
return False
# generate CA RSA key
execStr = self.templCreateKey%{'sslFile':self.sslFile,
'certKeyFile':CAKeyFile,
'sslBits':sslBits}
if execProg(execStr) is False:
self.printERROR(_("Can not execute '%s'")%execStr)
return False
if os.path.exists(CAKeyFile):
os.chown(CAKeyFile, uid,gid)
os.chmod(CAKeyFile, fileMode)
# create CA
execStr = self.templCreateCert%{'sslFile':self.sslFile,
'sslDays':sslDays,
'cnfFile':cnfFile,
'certKeyFile':CAKeyFile,
'certFile':CACertFile}
if execProg(execStr) is False:
self.printERROR(_("Can not execute '%s'")%execStr)
return False
if os.path.exists(CACertFile):
os.chown(CACertFile, uid,gid)
os.chmod(CACertFile, fileMode)
if os.path.exists(cnfFile):
os.remove(cnfFile)
# check certificate
return self.checkCertificate(CACertFile)
def createSignedCertificate(self,
sslCountry=sslCountry,
sslState=sslState,
sslLocality=sslLocality,
sslOrganization=sslOrganization,
sslUnit=sslUnit,
sslCommonName=sslCommonName,
sslEmail=sslEmail,
nsCertType=nsCertType,
sslDays=sslDays,
sslBits=sslBits,
userName=userName,
CAPath=CAPath,
CACertFileName=CACertFileName,
CAKeyFileName=CAKeyFileName,
CACrlFileName=CACrlFileName,
certFile=certFile,
fileMode=fileMode,
keyFile=keyFile,
csrFile=csrFile,
force=False):
'''Create signed CA certificate'''
certAndKeyFiles = [certFile, keyFile, csrFile]
foundCertFiles = map(lambda x: os.path.exists(x), certAndKeyFiles)
if not force and foundCertFiles[0] and foundCertFiles[1]:
return True
foundCertFiles = map(lambda x: x[1], filter(lambda x: x[0],
zip(foundCertFiles, certAndKeyFiles)))
# Удаляем файлы
map(lambda x: os.remove(x), foundCertFiles)
# получаем id и gid пользователя
try:
pwdObj = pwd.getpwnam(userName)
except:
self.printERROR(_("Not found user %s")%userName)
return False
uid = pwdObj.pw_uid
gid = pwdObj.pw_gid
# create dirs
for fileName in certAndKeyFiles:
dirName = os.path.split(fileName)[0]
if not os.path.exists(dirName):
self._createDir(dirName, uid=uid, gid=gid)
rCACertFile = os.path.join(self.rCACertPath, CACertFileName)
rCAKeyFile = os.path.join(self.rCAKeyPath, CAKeyFileName)
rCACrlFile = os.path.join(self.rCACrlPath, CACrlFileName)
rRandFile = os.path.join(self.rCAKeyPath,".rnd")
textCnf = self.templCnfCA%{'CAPath':CAPath,
'rCACertPath':self.rCACertPath,
'rCACrlPath':self.rCACrlPath,
'rDatabaseFileName':self.rDatabaseFileName,
'rCACertFile':rCACertFile,
'rSerialFileName':self.rSerialFileName,
'rCACrlFile':rCACrlFile,
'rCAKeyFile':rCAKeyFile,
'rRandFile':rRandFile,
'sslBits':sslBits,
'sslCountry':sslCountry,
'sslState':sslState,
'sslLocality':sslLocality,
'sslOrganization':sslOrganization,
'sslUnit':sslUnit,
'sslCommonName':sslCommonName,
'sslEmail':sslEmail,
'nsCertType':nsCertType}
cnfFile = self.createCnfFile(textCnf)
if cnfFile is False:
return False
# generate RSA key
execStr = self.templCreateKey%{'sslFile':self.sslFile,
'certKeyFile':keyFile,
'sslBits':sslBits}
if execProg(execStr) is False:
self.printERROR(_("Can not execute '%s'")%execStr)
return False
if os.path.exists(keyFile):
os.chown(keyFile, uid,gid)
os.chmod(keyFile, fileMode)
# generate request
templCreateReq = "%(sslFile)s req -new -days %(sslDays)s "\
"-config %(cnfFile)s -key %(certKeyFile)s "\
"-out %(certCsrFile)s"
execStr = self.templCreateReq%{'sslFile':self.sslFile,
'sslDays':sslDays,
'cnfFile':cnfFile,
'certKeyFile':keyFile,
'certCsrFile':csrFile}
if execProg(execStr) is False:
self.printERROR(_("Can not execute '%s'")%execStr)
return False
if os.path.exists(csrFile):
os.chown(csrFile, uid,gid)
os.chmod(csrFile, fileMode)
# set database attribute
databaseAttrFileName = os.path.join(CAPath, "index.dat.attr")
self._createFile(databaseAttrFileName, "unique_subject = no\n")
# generate signed cerificate
templCreateSignCert = "%(sslFile)s ca -batch -config %(cnfFile)s "\
"-policy policy_anything -days %(sslDays)s "\
"-out %(certFile)s -infiles %(certCsrFile)s"
execStr = self.templCreateSignCert%{'sslFile':self.sslFile,
'sslDays':sslDays,
'cnfFile':cnfFile,
'certFile':certFile,
'certCsrFile':csrFile}
if execProg(execStr) is False:
self.printERROR(_("Can not execute '%s'")%execStr)
return False
if os.path.exists(certFile):
os.chown(certFile, uid,gid)
os.chmod(certFile, fileMode)
if os.path.exists(cnfFile):
os.remove(cnfFile)
# check certificate
return self.checkCertificate(certFile)
def createCertificate(self,
sslCountry=sslCountry,
sslState=sslCountry,
sslLocality=sslLocality,
sslOrganization=sslOrganization,
sslUnit=sslUnit,
sslCommonName=sslCommonName,
sslEmail=sslEmail,
nsCertType=nsCertType,
sslDays=sslDays,
sslBits=sslBits,
userName=userName,
certFile=certFile,
fileMode=fileMode,
keyFile=keyFile):
"""Создает сертификат"""
certAndKeyFiles = [certFile, keyFile]
foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles)
@ -151,64 +524,44 @@ class encrypt(color_print):
return False
uid = pwdObj.pw_uid
gid = pwdObj.pw_gid
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)
textCnf=self.templCnfData%{'sslBits':sslBits,
'sslCountry':sslCountry,
'sslState':sslState,
'sslLocality':sslLocality,
'sslOrganization':sslOrganization,
'sslUnit':sslUnit,
'sslCommonName':sslCommonName,
'sslEmail':sslEmail,
'nsCertType':nsCertType}
cnfFile = self.createCnfFile(textCnf)
if cnfFile is False:
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)
# Создание конфигурационного файла
self._createFile(cnfFile, textCnf, 0, 0, 0600)
self._createDir(dirName, uid=uid, gid=gid)
# Создание сертификата
textLine = execProg(\
"%s req -new -x509 -nodes -config %s -days %s -out %s -keyout %s"\
%(sslFile, cnfFile, sslDays, certFile, keyFile))
textLine = execProg(
"%s req -new -x509 -nodes -config %s -days %s -out %s -keyout %s"
%(self.sslFile, cnfFile, sslDays, certFile, keyFile))
if textLine is False:
self.printERROR(_("Can not create certificate %s")%certFile)
return False
# Удаление конфигурационного файла
if os.path.exists(cnfFile):
os.remove(cnfFile)
# Меняем права
if os.path.exists(certFile):
os.chown(certFile, uid,gid)
os.chmod(certFile, certFileMode)
os.chmod(certFile, fileMode)
if os.path.exists(keyFile):
os.chown(keyFile, uid,gid)
os.chmod(keyFile, keyFileMode)
if textLine is False:
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:
self.printERROR(_("Can not create certificate %s")%certFile)
return False
return True
os.chmod(keyFile, fileMode)
return self.checkCertificate(certFile)
def _createDir(self, uid, gid, dirName, mode=0700):
def _createDir(self, dirName, uid=0, gid=0, mode=0700):
"""Создание пользовательской директории"""
if not os.path.exists(dirName):
os.makedirs(dirName)
@ -220,7 +573,7 @@ nsCertType = %s
self.printERROR(_("Path %s exists") %dirName)
return False
def _createFile(self, fileName, fileTxt, uid, gid, mode=0644):
def _createFile(self, fileName, fileTxt, uid=0, gid=0, mode=0600):
"""Создает пользовательский файл с содержимым
Если директория файла не существует то ошибка
@ -231,12 +584,13 @@ nsCertType = %s
return False
fd = os.open(fileName, os.O_CREAT)
os.close(fd)
os.chmod(fileName, mode)
os.chmod(fileName, 0700)
os.chown(fileName,uid,gid)
if fileTxt:
FD = open(fileName, "r+")
FD.write(fileTxt)
FD.close()
os.chmod(fileName, mode)
return True

Loading…
Cancel
Save