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-3-core/pym/core/server/bootstrap.py

392 lines
14 KiB

12 years ago
#-*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org
12 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 cert_cmd
12 years ago
import post_request
import datetime, subprocess, shutil
12 years ago
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
import os, hashlib, OpenSSL, pwd, socket, sys
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core3',sys.modules[__name__])
12 years ago
def createDate(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, cert_path, data_path, certbase, args):
error_flag = 0
if not os.path.isfile(cert):
error_flag = 1
print _('Certificate %s not found') %cert
if not os.path.isfile(key):
error_flag = 1
12 years ago
print _('Private key %s not found') %key
if os.path.isfile(cert) and os.path.isfile(key):
# 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():
12 years ago
print _('The certificate does not match the private key')
error_flag = 1
# check certificate date
cert_data = open(cert, 'r').read()
certobj = OpenSSL.crypto.load_certificate \
(OpenSSL.SSL.FILETYPE_PEM, cert_data)
certobj.get_notBefore()
notAfter = createDate(certobj.get_notAfter())
notBefore = createDate(certobj.get_notBefore())
date = datetime.datetime.now()
if notBefore > date:
12 years ago
print _('Certificate creation date later than current date')
error_flag = 1
elif notAfter < date:
12 years ago
print _('Certificate expired')
error_flag = 1
sys.exit(error_flag)
def init(cert, key, cert_path, data_path, certbase, args, port, user_name):
if args.remove_certificates:
key_force(cert_path, data_path)
new_serv_cert = False
if not check_serv_cert(cert_path):
12 years ago
print _('Generating the server certificate')
12 years ago
for step in range (2):
args = change_args(args, step)
create_server_cert(cert, key, cert_path, args, port)
new_serv_cert = True
else:
12 years ago
print _('Server certificate now exists.')
if new_serv_cert or not check_client_cert(user_name):
12 years ago
print _('Generating the client certificate')
create_client_cert(cert, cert_path, data_path, certbase, user_name)
else:
12 years ago
print _('Client certificate now exists.')
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):
client_cert_path = check_user_path(user_name)
server_host_name = socket.getfqdn()
if os.path.isfile(os.path.join(client_cert_path ,server_host_name+'.crt'))\
and os.path.isfile(os.path.join \
(client_cert_path, server_host_name+'.key')):
return True
return False
12 years ago
12 years ago
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
12 years ago
12 years ago
def create_server_cert(cert, key, cert_path, args, port):
cert_cmd.check_server_certificate(cert,key,cert_path,args,port,auto=True)
12 years ago
def create_client_cert(server_cert, cert_path, data_path, certbase, user_name):
client_cert_path = check_user_path(user_name)
if not client_cert_path:
12 years ago
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)
12 years ago
sign_certificate(req_id, cert_path, data_path)
get_certificate(cert_path,data_path,certbase,client_cert_path,user_name)
12 years ago
def check_user_path(user_name):
try:
pwdObj = pwd.getpwnam(user_name)
except KeyError, 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]:
if os.path.isfile(_file):
os.chown('/'.join([path[0],_file]),pwdObj.pw_uid,pwdObj.pw_gid)
os.chmod(directory, 0644)
return cert_dir
12 years ago
def create_request(server_cert, cert_path, data_path, certbase, \
client_cert_path, user_name):
server_host_name = socket.getfqdn()
12 years ago
key = os.path.join(client_cert_path, server_host_name + '.key')
12 years ago
#csr_file = cert_path + server_host_name +'.csr'
#pritn 'request file = ', csr_file
client_req_file = new_key_req(key, client_cert_path, server_host_name,
auto = True)
12 years ago
try:
pwdObj = pwd.getpwnam(user_name)
except KeyError, 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)
12 years ago
ip, mac, client_type = get_ip_mac_type()
data = open(client_req_file).read()
12 years ago
12 years ago
req_id = post_request.serv_post_client_request (data, data_path, ip, mac, \
client_type, certbase, cert_path)
12 years ago
fc = open(os.path.join(client_cert_path, 'req_id'), 'w')
fc.write(req_id)
12 years ago
fc.close()
return req_id
12 years ago
12 years ago
def sign_certificate(req_id, cert_path, data_path):
cert_cmd.sing_req_by_server(req_id, cert_path, data_path, auto = True)
12 years ago
def get_certificate(cert_path,data_path,certbase,client_cert_path,user_name):
req_id_file = os.path.join(client_cert_path, 'req_id')
if not os.path.exists(req_id_file):
12 years ago
print _("request not sent or file %s deleted") %req_id_file
12 years ago
return 1
fc = open(req_id_file, 'r')
12 years ago
req_id = fc.read()
fc.close()
server_host_name = socket.getfqdn()
12 years ago
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
12 years ago
return 1
request = open(req_file).read()
12 years ago
md5 = hashlib.md5()
md5.update(request)
md5sum = md5.hexdigest()
12 years ago
result = post_request.serv_get_client_cert (req_id, md5sum, data_path, \
12 years ago
certbase, cert_path)
cert = result[0]
if len (result) > 1:
ca_root = result[1]
else: None
12 years ago
if cert == '1':
12 years ago
print _('The signature request was rejected!')
12 years ago
return 1
elif cert == '2':
12 years ago
print _("The signature request has not been examined yet.")
12 years ago
print _("Your request ID = %s") %req_id
12 years ago
return 1
elif cert == '3':
12 years ago
print _("The signature request does not match earlier data.")
12 years ago
return 1
elif cert == '4':
12 years ago
print _("The request was sent from another IP.")
12 years ago
return 1
cert_file = os.path.join(client_cert_path, server_host_name + '.crt')
fc = open(cert_file, 'w')
12 years ago
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
12 years ago
12 years ago
if ca_root:
clVars = DataVarsCore()
clVars.importCore()
12 years ago
clVars.flIniFile()
system_ca_db = clVars.Get('cl_glob_root_cert')
if os.path.exists(system_ca_db):
if ca_root in open(system_ca_db, 'r').read():
return 0
12 years ago
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")
12 years ago
md5 = hashlib.md5()
md5.update(ca_root)
md5sum = md5.hexdigest()
12 years ago
12 years ago
if not os.path.exists(root_cert_md5):
fc = open(root_cert_md5,"w")
fc.close()
12 years ago
12 years ago
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, ca_root)
Issuer = certobj.get_issuer().get_components()
for item in Issuer:
if item[0] == 'CN':
filename = item[1]
12 years ago
12 years ago
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)
12 years ago
12 years ago
if not filename:
12 years ago
print _('Field "CN" not found in the certificate!')
12 years ago
return 1
12 years ago
ca_cert = os.path.join(ca_dir, filename)
fd = open(ca_cert, 'w')
12 years ago
fd.write(ca_root)
fd.close()
os.chown(ca_cert, pwdObj.pw_uid, pwdObj.pw_gid)
os.chmod(ca_cert, 0644)
12 years ago
user_root_cert = os.path.join(ca_dir, 'ca_root.crt')
12 years ago
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:
12 years ago
# 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:
12 years ago
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)