#!/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)