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.
246 lines
8.3 KiB
246 lines
8.3 KiB
#!/usr/bin/python
|
|
#-*- coding: utf-8 -*-
|
|
|
|
# Copyright 2012 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 cert_cmd
|
|
import post_request
|
|
|
|
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 import ip as ip_mod
|
|
import os, hashlib, OpenSSL, pwd, socket
|
|
from os import path
|
|
|
|
def init(cert, key, cert_path, data_path, certbase, args, port, user_name):
|
|
try:
|
|
pwdObj = pwd.getpwnam(user_name)
|
|
except KeyError, e:
|
|
print e
|
|
return 1
|
|
new_serv_cert = False
|
|
if not check_serv_cert(cert_path):
|
|
print 'Generate 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 already exists'
|
|
|
|
if new_serv_cert or not check_client_cert(user_name):
|
|
print 'Generate Client Certificate'
|
|
create_client_cert(cert, cert_path, data_path, certbase, user_name)
|
|
change_owner(pwdObj, user_name)
|
|
else:
|
|
print 'Client certificate already exists'
|
|
|
|
def check_serv_cert(cert_path):
|
|
if path.isfile (cert_path + '/server.crt') and path.isfile \
|
|
(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 path.isfile (client_cert_path + server_host_name + '.crt') and \
|
|
path.isfile (client_cert_path + server_host_name + '.key'):
|
|
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):
|
|
client_cert_path = check_user_path(user_name)
|
|
if not client_cert_path:
|
|
print 'not client_cert_path'
|
|
return 1
|
|
req_id = create_request(server_cert, cert_path, data_path, certbase, \
|
|
client_cert_path)
|
|
sign_certificate(req_id, cert_path, data_path)
|
|
get_certificate(cert_path, data_path, certbase, client_cert_path)
|
|
|
|
def check_user_path(user_name):
|
|
if user_name == 'root':
|
|
home_dir = '/root'
|
|
else:
|
|
home_dir = '/home/' + user_name
|
|
if not path.isdir(home_dir):
|
|
print 'Not fount user %s' %user_name
|
|
return None
|
|
calc_dir = home_dir + '/.calculate'
|
|
if not path.isdir(calc_dir):
|
|
os.makedirs(calc_dir)
|
|
client_cert_path = calc_dir + '/client_cert/'
|
|
if not path.isdir(client_cert_path):
|
|
os.makedirs(client_cert_path)
|
|
return client_cert_path
|
|
|
|
def create_request(server_cert, cert_path, data_path, certbase,client_cert_path):
|
|
server_host_name = socket.getfqdn()
|
|
|
|
key = client_cert_path + server_host_name + '.key'
|
|
#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)
|
|
|
|
ip, mac, client_type = get_ip_mac_type()
|
|
data = open(client_req_file).read()
|
|
|
|
req_id = post_request.serv_post_client_request (data, data_path, ip, mac, \
|
|
client_type, certbase, cert_path)
|
|
|
|
fc = open(client_cert_path + 'req_id', 'w')
|
|
fc.write(req_id)
|
|
fc.close()
|
|
return req_id
|
|
|
|
def sign_certificate(req_id, cert_path, data_path):
|
|
cert_cmd.sing_req_by_server(req_id, cert_path, data_path, auto = True)
|
|
|
|
def get_certificate(cert_path, data_path, certbase, client_cert_path):
|
|
if not os.path.exists(client_cert_path + 'req_id'):
|
|
print _("request was not sent or deleted file %s") \
|
|
%(client_cert_path + 'req_id')
|
|
return 1
|
|
fc = open(client_cert_path + 'req_id', 'r')
|
|
req_id = fc.read()
|
|
fc.close()
|
|
|
|
server_host_name = socket.getfqdn()
|
|
|
|
if not os.path.exists(client_cert_path + server_host_name + '.csr'):
|
|
print _('Request %s not found') %(client_cert_path + server_host_name + '.csr')
|
|
return 1
|
|
request = open(client_cert_path + server_host_name + '.csr').read()
|
|
md5 = hashlib.md5()
|
|
md5.update(request)
|
|
md5sum = md5.hexdigest()
|
|
|
|
result = post_request.serv_get_client_cert (req_id, md5sum, data_path, \
|
|
certbase, cert_path)
|
|
|
|
cert = result[0]
|
|
ca_root = result[1]
|
|
if cert == '1':
|
|
print _('Request to sign is rejected!')
|
|
return 1
|
|
elif cert == '2':
|
|
print _("Request for the signing has not yet reviewed.")
|
|
print _("Your request id = %s") %req_id
|
|
return 1
|
|
elif cert == '3':
|
|
print _("Request on signature does not match sent earlier.")
|
|
return 1
|
|
elif cert == '4':
|
|
print _("Request was sent from another ip.")
|
|
return 1
|
|
fc = open(client_cert_path + server_host_name + '.crt', 'w')
|
|
fc.write(cert)
|
|
fc.close()
|
|
os.unlink(client_cert_path + 'req_id')
|
|
print 'OK. Certificate save. 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 open(system_ca_db, 'r').read():
|
|
return 0
|
|
|
|
if not path.isdir (client_cert_path + 'ca'):
|
|
os.makedirs(client_cert_path + 'ca')
|
|
root_cert_md5 = client_cert_path + "ca/cert_list"
|
|
|
|
md5 = hashlib.md5()
|
|
md5.update(ca_root)
|
|
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, 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 _('Not found field "CN" in certificate!')
|
|
return 1
|
|
|
|
fd = open(client_cert_path + 'ca/' + filename, 'w')
|
|
fd.write(ca_root)
|
|
fd.close()
|
|
|
|
user_root_cert = client_cert_path + "ca/ca_root.crt"
|
|
fa = open(user_root_cert, 'a')
|
|
fa.write(ca_root)
|
|
fa.close()
|
|
print _("filename = "), filename
|
|
print _("CERTIFICATE ADD")
|
|
else:
|
|
print _("file with ca certificates exists")
|
|
return 0
|
|
|
|
def change_owner(pwdObj, user_name):
|
|
if user_name == 'root':
|
|
return 1
|
|
else:
|
|
home_dir = '/home/' + user_name
|
|
|
|
for path in os.walk(home_dir + '/.calculate'):
|
|
os.chown(path[0], pwdObj.pw_uid, pwdObj.pw_gid)
|
|
for file in path[2]:
|
|
os.chown('/'.join([path[0], file]), pwdObj.pw_uid, pwdObj.pw_gid)
|
|
|