mirror of
https://port.numenaute.org/aleajactaest/khanat-code-old.git
synced 2024-11-25 16:26:18 +00:00
Manager can be use TLS1.2
This commit is contained in:
parent
5aab6b97f1
commit
d7745e451a
5 changed files with 545 additions and 42 deletions
|
@ -54,6 +54,8 @@ import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import http.client
|
import http.client
|
||||||
import json
|
import json
|
||||||
|
import socket
|
||||||
|
import ssl
|
||||||
|
|
||||||
def cmp_to_key():
|
def cmp_to_key():
|
||||||
'compare key (check if int or other)'
|
'compare key (check if int or other)'
|
||||||
|
@ -92,14 +94,52 @@ def cmp_to_key():
|
||||||
return self.obj != other.obj
|
return self.obj != other.obj
|
||||||
return K
|
return K
|
||||||
|
|
||||||
|
class HTTPSConnectionCertificate(http.client.HTTPConnection):
|
||||||
|
""" Class HTTP connection with check certificate (if certicate is defined) """
|
||||||
|
def __init__(self, key_file, cert_file, ca_cert, host='localhost', port=8000, timeout=10):
|
||||||
|
"""
|
||||||
|
Constructor
|
||||||
|
"""
|
||||||
|
logging.debug("constructor")
|
||||||
|
http.client.HTTPConnection.__init__(self, host, port, timeout)
|
||||||
|
self.key_file = key_file
|
||||||
|
self.cert_file = cert_file
|
||||||
|
self.ca_cert = ca_cert
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
"""
|
||||||
|
connect in https (and check certificate if defined)
|
||||||
|
"""
|
||||||
|
logging.debug("connect launched")
|
||||||
|
sock = socket.create_connection((self.host, self.port), self.timeout)
|
||||||
|
# If there's no CA File, don't force Server Certificate Check
|
||||||
|
if self.ca_cert:
|
||||||
|
logging.debug("key_file: " + self.key_file)
|
||||||
|
logging.debug("cert_file: " + self.cert_file)
|
||||||
|
logging.debug("ca_cert: " + self.ca_cert)
|
||||||
|
self.sock = ssl.wrap_socket(sock,
|
||||||
|
self.key_file,
|
||||||
|
self.cert_file,
|
||||||
|
ca_certs=self.ca_cert,
|
||||||
|
cert_reqs=ssl.CERT_REQUIRED,
|
||||||
|
ssl_version=ssl.PROTOCOL_TLSv1_2 #PROTOCOL_SSLv23 #, ciphers="ADH-AES256-SHA"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE)
|
||||||
|
|
||||||
|
|
||||||
def send_json(jsonin={}, command='GET', path='/', host='localhost', port=8000, raw_data=False, remove_color=False,
|
def send_json(jsonin={}, command='GET', path='/', host='localhost', port=8000, raw_data=False, remove_color=False,
|
||||||
key_file=None, cert_file=None):
|
key_file=None, cert_file=None, ca_cert=None, timeout=10):
|
||||||
"send command with https & json format"
|
"""
|
||||||
conn = http.client.HTTPSConnection(host=host, port=port, key_file=key_file, cert_file=cert_file )
|
send command with https & json format
|
||||||
|
"""
|
||||||
|
|
||||||
|
conn = HTTPSConnectionCertificate(host=host, port=port, key_file=key_file, cert_file=cert_file, ca_cert=ca_cert, timeout=timeout)
|
||||||
conn.putrequest(command, path)
|
conn.putrequest(command, path)
|
||||||
out=json.dumps(jsonin)
|
out=json.dumps(jsonin)
|
||||||
conn.putheader('Content-type', 'application/json')
|
conn.putheader('Content-type', 'application/json')
|
||||||
#length = int(self.headers.getheader('content-length'))
|
|
||||||
conn.putheader('Content-length', len(out))
|
conn.putheader('Content-length', len(out))
|
||||||
conn.endheaders()
|
conn.endheaders()
|
||||||
conn.send(bytes(out, "utf-8"))
|
conn.send(bytes(out, "utf-8"))
|
||||||
|
@ -126,8 +166,8 @@ def send_json(jsonin={}, command='GET', path='/', host='localhost', port=8000, r
|
||||||
print("%s: %s %s" % (key, msgjson[key], endText))
|
print("%s: %s %s" % (key, msgjson[key], endText))
|
||||||
|
|
||||||
|
|
||||||
def main(server, command, program, action, firstline, fileLog, logLevel, show_log_console, port=8000,
|
def main(host, command, program, action, firstline, fileLog, logLevel, show_log_console, port=8000,
|
||||||
raw_data=False, remove_color=False, key_file=None, cert_file=None):
|
raw_data=False, remove_color=False, key_file=None, cert_file=None, ca_cert=None):
|
||||||
# Manage log
|
# Manage log
|
||||||
logging.getLogger('logging')
|
logging.getLogger('logging')
|
||||||
numeric_level = getattr(logging, logLevel.upper(), None)
|
numeric_level = getattr(logging, logLevel.upper(), None)
|
||||||
|
@ -142,19 +182,26 @@ def main(server, command, program, action, firstline, fileLog, logLevel, show_lo
|
||||||
format='%(asctime)s %(levelname)s [pid:%(process)d] [%(funcName)s:%(lineno)d] %(message)s')
|
format='%(asctime)s %(levelname)s [pid:%(process)d] [%(funcName)s:%(lineno)d] %(message)s')
|
||||||
# Send command
|
# Send command
|
||||||
if command == 'START' or command == 'STOP':
|
if command == 'START' or command == 'STOP':
|
||||||
send_json({'name': program}, 'POST', "/" + command, server, port)
|
send_json({'name': program}, 'POST', "/" + command, host, port, key_file=key_file,
|
||||||
|
cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'STATUS':
|
elif command == 'STATUS':
|
||||||
send_json({'name': program}, 'GET', "/" + command, server, port)
|
send_json({'name': program}, 'GET', "/" + command, host, port, key_file=key_file,
|
||||||
|
cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'ACTION':
|
elif command == 'ACTION':
|
||||||
send_json({'name': program, 'action' : action}, 'POST', "/" + command, server, port)
|
send_json({'name': program, 'action' : action}, 'POST', "/" + command, host, port,
|
||||||
|
key_file=key_file, cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'LOG':
|
elif command == 'LOG':
|
||||||
send_json({'name': program, 'first-line' : firstline }, 'GET', "/" + command, server, port, raw_data, remove_color)
|
send_json({'name': program, 'first-line' : firstline }, 'GET', "/" + command, host, port, raw_data,
|
||||||
|
remove_color, key_file=key_file, cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'LIST':
|
elif command == 'LIST':
|
||||||
send_json({}, 'GET', "/" + command, server, port)
|
send_json({}, 'GET', "/" + command, host, port, key_file=key_file,
|
||||||
|
cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'SHUTDOWN' or command == 'STARTALL' or command == 'STOPALL':
|
elif command == 'SHUTDOWN' or command == 'STARTALL' or command == 'STOPALL':
|
||||||
send_json({}, 'POST', "/" + command, server, port)
|
send_json({}, 'POST', "/" + command, host, port, key_file=key_file,
|
||||||
|
cert_file=cert_file, ca_cert=ca_cert)
|
||||||
elif command == 'STATUSALL':
|
elif command == 'STATUSALL':
|
||||||
send_json({}, 'GET', "/" + command, server, port)
|
send_json({}, 'GET', "/" + command, host, port, key_file=key_file,
|
||||||
|
cert_file=cert_file, ca_cert=ca_cert)
|
||||||
else:
|
else:
|
||||||
logging.error("command unknown (%s)" % command)
|
logging.error("command unknown (%s)" % command)
|
||||||
|
|
||||||
|
@ -170,7 +217,8 @@ if __name__ == '__main__':
|
||||||
default='INFO', help='log level [DEBUG, INFO, WARNING, ERROR')
|
default='INFO', help='log level [DEBUG, INFO, WARNING, ERROR')
|
||||||
parser.add_argument('--key', help='key file', default=None)
|
parser.add_argument('--key', help='key file', default=None)
|
||||||
parser.add_argument('--cert', help='cert file', default=None)
|
parser.add_argument('--cert', help='cert file', default=None)
|
||||||
parser.add_argument('--server', help='server khganat', default='127.0.0.1')
|
parser.add_argument('--ca_cert', help='ca_cert file', default=None)
|
||||||
|
parser.add_argument('--host', help='server khganat', default='127.0.0.1')
|
||||||
parser.add_argument('--command', help='command send to khganat', default='/STATUS')
|
parser.add_argument('--command', help='command send to khganat', default='/STATUS')
|
||||||
parser.add_argument('--program', help='program khaganat id ', default='aes')
|
parser.add_argument('--program', help='program khaganat id ', default='aes')
|
||||||
parser.add_argument('--action', help='action ', default='')
|
parser.add_argument('--action', help='action ', default='')
|
||||||
|
@ -181,9 +229,9 @@ if __name__ == '__main__':
|
||||||
parser.add_argument( '--keep-color', action='store_true',
|
parser.add_argument( '--keep-color', action='store_true',
|
||||||
help='some message have color define, by default we reset the color (this option keep current color state)', default=False)
|
help='some message have color define, by default we reset the color (this option keep current color state)', default=False)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
main(server = args.server, action = args.action, firstline = args.firstline,
|
main(host = args.host, action = args.action, firstline = args.firstline,
|
||||||
command = args.command, program = args.program, fileLog = args.filelog,
|
command = args.command, program = args.program, fileLog = args.filelog,
|
||||||
logLevel=args.log, show_log_console=args.show_log_console,
|
logLevel=args.log, show_log_console=args.show_log_console,
|
||||||
raw_data = args.raw_data,
|
raw_data = args.raw_data,
|
||||||
key_file=args.key, cert_file=args.cert,
|
key_file=args.key, cert_file=args.cert, ca_cert=args.ca_cert,
|
||||||
remove_color=not args.keep_color)
|
remove_color=not args.keep_color)
|
||||||
|
|
422
code/khaganat/tools/create_certificate.py
Executable file
422
code/khaganat/tools/create_certificate.py
Executable file
|
@ -0,0 +1,422 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# script to create certificate use for test
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017 AleaJactaEst
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate all certificates
|
||||||
|
CA certificate (emulate CA certificate)
|
||||||
|
Appli certification (our global certificate, use to sign our key)
|
||||||
|
Server certificate (our key & certificate for server side)
|
||||||
|
Client certificate (our key & certificate for server side)
|
||||||
|
|
||||||
|
CA
|
||||||
|
\
|
||||||
|
Apppli
|
||||||
|
/ \
|
||||||
|
Server Client
|
||||||
|
|
||||||
|
Example command to generate all certificate :
|
||||||
|
create_certificate.py --show-log-console --log debug
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class Certificate:
|
||||||
|
def __init__(self,
|
||||||
|
openssl,
|
||||||
|
workdir_cert_ca,
|
||||||
|
workdir_cert_appli,
|
||||||
|
passca='OpenNelCA9439',
|
||||||
|
passappli='OpenNelAPPLI1097',
|
||||||
|
countryName='FR',
|
||||||
|
stateOrProvinceName='France',
|
||||||
|
localityName='Paris',
|
||||||
|
organizationName='khanat',
|
||||||
|
commonName='khanat.org',
|
||||||
|
sizeCa = 4096,
|
||||||
|
sizeAppli = 4096,
|
||||||
|
sizeChild = 2048):
|
||||||
|
self.workdir_cert_ca = os.path.abspath(workdir_cert_ca)
|
||||||
|
self.workdir_cert_appli = os.path.abspath(workdir_cert_appli)
|
||||||
|
self.openssl = openssl
|
||||||
|
self.passca = passca
|
||||||
|
self.passappli = passappli
|
||||||
|
self.countryName = countryName
|
||||||
|
self.stateOrProvinceName = stateOrProvinceName
|
||||||
|
self.localityName = localityName
|
||||||
|
self.organizationName = organizationName
|
||||||
|
self.commonName = commonName
|
||||||
|
self.configca = os.path.join(self.workdir_cert_ca, 'openssl.cnf')
|
||||||
|
self.configappli = os.path.join(self.workdir_cert_appli, 'openssl.cnf')
|
||||||
|
self.sizeCa = sizeCa
|
||||||
|
self.sizeAppli = sizeAppli
|
||||||
|
self.sizeChild = sizeChild
|
||||||
|
|
||||||
|
def directory_create(self, dirpath):
|
||||||
|
if not dir:
|
||||||
|
raise ValueError
|
||||||
|
if not os.path.exists(dirpath):
|
||||||
|
os.makedirs(dirpath)
|
||||||
|
|
||||||
|
def SendCommandOpenssl(self, args):
|
||||||
|
command = '%s %s' % (self.openssl, args)
|
||||||
|
logging.debug("command:%s" % command)
|
||||||
|
code = subprocess.call(command.split(), stdout=sys.stdout,
|
||||||
|
stderr=sys.stderr)
|
||||||
|
if code != 0:
|
||||||
|
logging.error("Command '%s' return code:%d" % (command, code))
|
||||||
|
exit(code)
|
||||||
|
|
||||||
|
def writeConfigOpenssl(self, config, dirpath, certfile, keyfile):
|
||||||
|
with open(config, 'w') as f:
|
||||||
|
f.write('[ ca ]\n'
|
||||||
|
'default_ca = CA_default\n'
|
||||||
|
'\n[ CA_default ]\n'
|
||||||
|
'dir = %s\n'
|
||||||
|
'certs = $dir/certs\n'
|
||||||
|
'crl_dir = $dir/crl\n'
|
||||||
|
'database = $dir/index.txt\n'
|
||||||
|
'new_certs_dir = $dir/newcerts\n'
|
||||||
|
'certificate = $dir/certs/%s\n'
|
||||||
|
'serial = $dir/serial\n'
|
||||||
|
'crlnumber = $dir/crlnumber\n'
|
||||||
|
'crl = $dir/crl/%s\n'
|
||||||
|
'private_key = $dir/private/%s\n'
|
||||||
|
'RANDFILE = $dir/private/.rand\n'
|
||||||
|
'name_opt = ca_default\n'
|
||||||
|
'cert_opt = ca_default\n'
|
||||||
|
'default_days = 390\n'
|
||||||
|
'default_crl_days = 30\n'
|
||||||
|
'default_md = sha256\n'
|
||||||
|
'preserve = no\n'
|
||||||
|
'policy = policy_match\n'
|
||||||
|
'crl_extensions = crl_ext\n'
|
||||||
|
'unique_subject = no\n'
|
||||||
|
'\n[ policy_match ]\n'
|
||||||
|
'countryName = match\n'
|
||||||
|
'stateOrProvinceName = match\n'
|
||||||
|
'organizationName = match\n'
|
||||||
|
'organizationalUnitName = optional\n'
|
||||||
|
'commonName = supplied\n'
|
||||||
|
'emailAddress = optional\n'
|
||||||
|
'\n[ req ]\n'
|
||||||
|
'default_bits = 2048\n'
|
||||||
|
'distinguished_name = req_distinguished_name\n'
|
||||||
|
'x509_extensions = v3_ca\n'
|
||||||
|
'string_mask = utf8only\n'
|
||||||
|
'unique_subject = no\n'
|
||||||
|
'\n[ server_cert ]\n'
|
||||||
|
'basicConstraints=CA:false\n'
|
||||||
|
'nsComment = "OpenSSL Generated Certificate"\n'
|
||||||
|
'subjectKeyIdentifier=hash\n'
|
||||||
|
'authorityKeyIdentifier=keyid,issuer:always\n'
|
||||||
|
'keyUsage = critical, digitalSignature, keyEncipherment\n'
|
||||||
|
'nsCertType = server\n'
|
||||||
|
'\n[ client_cert ]\n'
|
||||||
|
'basicConstraints=CA:false\n'
|
||||||
|
'nsComment = "OpenSSL Generated Certificate"\n'
|
||||||
|
'subjectKeyIdentifier=hash\n'
|
||||||
|
'authorityKeyIdentifier=keyid:always,issuer\n'
|
||||||
|
'keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment\n'
|
||||||
|
'nsCertType = client\n'
|
||||||
|
'\n[ v3_ca ]\n'
|
||||||
|
'basicConstraints=critical, CA:true\n'
|
||||||
|
'nsComment = "OpenSSL Generated Certificate"\n'
|
||||||
|
'subjectKeyIdentifier=hash\n'
|
||||||
|
'authorityKeyIdentifier=keyid:always,issuer\n'
|
||||||
|
'keyUsage = critical, digitalSignature, cRLSign, keyCertSign\n'
|
||||||
|
'\n[ v3_application_ca ]\n'
|
||||||
|
'basicConstraints=critical, CA:true, pathlen:0\n'
|
||||||
|
'nsComment = "OpenSSL Generated Certificate"\n'
|
||||||
|
'subjectKeyIdentifier=hash\n'
|
||||||
|
'authorityKeyIdentifier=keyid:always,issuer\n'
|
||||||
|
'keyUsage = critical, digitalSignature, cRLSign, keyCertSign\n'
|
||||||
|
'\n[ req_distinguished_name ]\n'
|
||||||
|
'countryName = Country Name (2 letter code)\n'
|
||||||
|
'countryName_default = FR\n'
|
||||||
|
'countryName_min = 2\n'
|
||||||
|
'countryName_max = 2\n'
|
||||||
|
'stateOrProvinceName = State or Province Name (full name)\n'
|
||||||
|
'stateOrProvinceName_default = France\n'
|
||||||
|
'localityName = Locality Name (eg, city)\n'
|
||||||
|
'0.organizationName = Organization Name (eg, company)\n'
|
||||||
|
'0.organizationName_default = Khanat\n'
|
||||||
|
'organizationalUnitName = Organizational Unit Name (eg, section)\n'
|
||||||
|
'commonName = Common Name (e.g. server FQDN or YOUR name)\n'
|
||||||
|
'commonName_max = 64\n'
|
||||||
|
'emailAddress = Email Address\n'
|
||||||
|
'emailAddress_max = 64\n'
|
||||||
|
'\n[ crl_ext ]\n'
|
||||||
|
'authorityKeyIdentifier=keyid:always\n'
|
||||||
|
% (dirpath, certfile, 'cacrl.pem', keyfile))
|
||||||
|
|
||||||
|
def createCACertificate(self):
|
||||||
|
logging.info("Create CA Certificate")
|
||||||
|
# Create directory
|
||||||
|
certfilename = 'cacert.pem'
|
||||||
|
keyfilename = 'cakey.pem'
|
||||||
|
self.directory_create(self.workdir_cert_ca)
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_ca, 'certs'))
|
||||||
|
private=os.path.join(self.workdir_cert_ca, 'private')
|
||||||
|
self.directory_create(private)
|
||||||
|
os.chmod(private, stat.S_IEXEC | stat.S_IWUSR | stat.S_IRUSR)
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_ca, 'crl'))
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_ca, 'newcerts'))
|
||||||
|
# Create files use in CA
|
||||||
|
index = os.path.join(self.workdir_cert_ca, 'index.txt')
|
||||||
|
with open(index, 'w') as f:
|
||||||
|
f.write('')
|
||||||
|
serial = os.path.join(self.workdir_cert_ca, 'serial')
|
||||||
|
with open(serial, 'w') as f:
|
||||||
|
f.write('10')
|
||||||
|
# Create configuration
|
||||||
|
self.writeConfigOpenssl(self.configca, self.workdir_cert_ca, certfilename, keyfilename)
|
||||||
|
# Create private key for our CA
|
||||||
|
keyfile = os.path.join(self.workdir_cert_ca, 'private', keyfilename)
|
||||||
|
self.SendCommandOpenssl('genrsa -aes256 -out %s -passout pass:%s %d' % (keyfile, self.passca, self.sizeCa))
|
||||||
|
os.chmod(keyfile, stat.S_IEXEC | stat.S_IWUSR | stat.S_IRUSR)
|
||||||
|
# Create certificate for our CA
|
||||||
|
certfile = os.path.join(self.workdir_cert_ca, 'certs', certfilename)
|
||||||
|
self.SendCommandOpenssl('req '
|
||||||
|
'-config %s '
|
||||||
|
'-key %s '
|
||||||
|
'-passin pass:%s '
|
||||||
|
'-new '
|
||||||
|
'-x509 '
|
||||||
|
'-days 390 '
|
||||||
|
'-sha256 '
|
||||||
|
'-extensions v3_ca '
|
||||||
|
'-out %s '
|
||||||
|
'-subj /C=%s/ST=%s/L=%s/O=%s/CN=%s' % (self.configca,
|
||||||
|
keyfile,
|
||||||
|
self.passca,
|
||||||
|
certfile,
|
||||||
|
self.countryName,
|
||||||
|
self.stateOrProvinceName,
|
||||||
|
self.localityName,
|
||||||
|
self.organizationName,
|
||||||
|
self.commonName))
|
||||||
|
os.chmod(certfile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||||
|
|
||||||
|
# Check certificate
|
||||||
|
self.SendCommandOpenssl('x509 -noout -text -in %s' % certfile)
|
||||||
|
|
||||||
|
def createApplicationCertificate(self):
|
||||||
|
logging.info("Create Application Certificate")
|
||||||
|
certfilename = 'applicert.pem'
|
||||||
|
csrfilename = 'applicsr.pem'
|
||||||
|
keyfilename = 'applikey.pem'
|
||||||
|
# Create directory
|
||||||
|
self.directory_create(self.workdir_cert_appli)
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_appli, 'certs'))
|
||||||
|
private=os.path.join(self.workdir_cert_appli, 'private')
|
||||||
|
self.directory_create(private)
|
||||||
|
os.chmod(private, stat.S_IEXEC | stat.S_IWUSR | stat.S_IRUSR)
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_appli, 'crl'))
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_appli, 'newcerts'))
|
||||||
|
self.directory_create(os.path.join(self.workdir_cert_appli, 'csr'))
|
||||||
|
# Create files use in CA
|
||||||
|
index = os.path.join(self.workdir_cert_appli, 'index.txt')
|
||||||
|
with open(index, 'w') as f:
|
||||||
|
f.write('')
|
||||||
|
serial = os.path.join(self.workdir_cert_appli, 'serial')
|
||||||
|
with open(serial, 'w') as f:
|
||||||
|
f.write('10')
|
||||||
|
serial = os.path.join(self.workdir_cert_appli, 'crlnumber')
|
||||||
|
with open(serial, 'w') as f:
|
||||||
|
f.write('10')
|
||||||
|
# Create configuration
|
||||||
|
self.writeConfigOpenssl(self.configappli, self.workdir_cert_appli, certfilename, keyfilename)
|
||||||
|
# Create private key for our Application
|
||||||
|
keyfile = os.path.join(self.workdir_cert_appli, 'private', keyfilename)
|
||||||
|
self.SendCommandOpenssl('genrsa -aes256 -out %s -passout pass:%s %d' % (keyfile,
|
||||||
|
self.passappli,
|
||||||
|
self.sizeAppli))
|
||||||
|
os.chmod(keyfile, stat.S_IEXEC | stat.S_IWUSR | stat.S_IRUSR)
|
||||||
|
# Create certificate for our CA
|
||||||
|
csrfile = os.path.join(self.workdir_cert_appli, 'csr', csrfilename)
|
||||||
|
self.SendCommandOpenssl('req '
|
||||||
|
'-config %s '
|
||||||
|
'-new '
|
||||||
|
'-sha256 '
|
||||||
|
'-passin pass:%s '
|
||||||
|
'-key %s '
|
||||||
|
'-out %s '
|
||||||
|
'-subj /C=%s/ST=%s/L=%s/O=%s/CN=%s' % (self.configappli,
|
||||||
|
self.passappli,
|
||||||
|
keyfile,
|
||||||
|
csrfile,
|
||||||
|
self.countryName,
|
||||||
|
self.stateOrProvinceName,
|
||||||
|
self.localityName,
|
||||||
|
self.organizationName,
|
||||||
|
self.commonName))
|
||||||
|
os.chmod(csrfile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||||
|
certfile = os.path.join(self.workdir_cert_appli, 'certs', certfilename)
|
||||||
|
self.SendCommandOpenssl('ca '
|
||||||
|
'-config %s '
|
||||||
|
'-extensions v3_application_ca '
|
||||||
|
'-days 390 '
|
||||||
|
'-notext '
|
||||||
|
'-md sha256 '
|
||||||
|
'-passin pass:%s '
|
||||||
|
'-in %s '
|
||||||
|
'-batch '
|
||||||
|
'-out %s ' % (self.configca,
|
||||||
|
self.passca,
|
||||||
|
csrfile,
|
||||||
|
certfile))
|
||||||
|
os.chmod(csrfile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||||
|
self.SendCommandOpenssl('x509 -noout -text -in %s' % certfile)
|
||||||
|
certcafilename = os.path.join(self.workdir_cert_ca, 'certs', 'cacert.pem')
|
||||||
|
self.SendCommandOpenssl('verify -CAfile %s %s' % (certcafilename, certfile))
|
||||||
|
# concat applicert & cacert
|
||||||
|
cachainfile = os.path.join(self.workdir_cert_appli, 'certs', 'cachaincert.pem')
|
||||||
|
with open(cachainfile, 'w') as outfp:
|
||||||
|
with open(certfile, 'r') as infp:
|
||||||
|
outfp.write(infp.read())
|
||||||
|
with open(certcafilename, 'r') as infp:
|
||||||
|
outfp.write(infp.read())
|
||||||
|
|
||||||
|
def createChildCertificate(self, childname, extension):
|
||||||
|
keyfilename = "%skey.pem" % childname
|
||||||
|
csrfilename = "%scsr.pem" % childname
|
||||||
|
certfilename = "%scert.pem" % childname
|
||||||
|
keyfile = os.path.join(self.workdir_cert_appli, 'private', keyfilename)
|
||||||
|
self.SendCommandOpenssl('genrsa -out %s %d' % (keyfile, self.sizeChild))
|
||||||
|
csrfile = os.path.join(self.workdir_cert_appli, 'csr', csrfilename)
|
||||||
|
self.SendCommandOpenssl('req '
|
||||||
|
'-config %s '
|
||||||
|
'-new '
|
||||||
|
'-sha256 '
|
||||||
|
'-key %s '
|
||||||
|
'-out %s '
|
||||||
|
'-subj /C=%s/ST=%s/L=%s/O=%s/CN=%s' % (self.configappli,
|
||||||
|
keyfile,
|
||||||
|
csrfile,
|
||||||
|
self.countryName,
|
||||||
|
self.stateOrProvinceName,
|
||||||
|
self.localityName,
|
||||||
|
self.organizationName,
|
||||||
|
self.commonName))
|
||||||
|
certfile = os.path.join(self.workdir_cert_appli, 'certs', certfilename)
|
||||||
|
self.SendCommandOpenssl('ca '
|
||||||
|
'-config %s '
|
||||||
|
'-extensions %s '
|
||||||
|
'-days 390 '
|
||||||
|
'-notext '
|
||||||
|
'-md sha256 '
|
||||||
|
'-passin pass:%s '
|
||||||
|
'-in %s '
|
||||||
|
'-batch '
|
||||||
|
'-out %s ' % (self.configappli,
|
||||||
|
extension,
|
||||||
|
self.passappli,
|
||||||
|
csrfile,
|
||||||
|
certfile))
|
||||||
|
self.SendCommandOpenssl('x509 -noout -text -in %s' % (certfile))
|
||||||
|
certcafilename = os.path.join(self.workdir_cert_appli, 'certs', 'cachaincert.pem')
|
||||||
|
self.SendCommandOpenssl('verify -CAfile %s %s' % (certcafilename, certfile))
|
||||||
|
|
||||||
|
|
||||||
|
def main(fileLog, logLevel, show_log_console,
|
||||||
|
workdir_cert_ca, workdir_cert_appli, openssl,
|
||||||
|
sizeCa, sizeAppli, sizeChild,
|
||||||
|
passca, passappli,
|
||||||
|
countryName, stateOrProvinceName, localityName, organizationName, commonName):
|
||||||
|
""" Main function """
|
||||||
|
# Manage log
|
||||||
|
logging.getLogger('logging')
|
||||||
|
numeric_level = getattr(logging, logLevel.upper(), None)
|
||||||
|
if not isinstance(numeric_level, int):
|
||||||
|
raise ValueError('Invalid log level: %s' % logLevel)
|
||||||
|
handlers=[]
|
||||||
|
if show_log_console:
|
||||||
|
handlers.append(logging.StreamHandler())
|
||||||
|
if fileLog:
|
||||||
|
handlers.append(logging.FileHandler(fileLog.name))
|
||||||
|
logging.basicConfig(handlers=handlers, level=numeric_level,
|
||||||
|
format='%(asctime)s %(levelname)s [pid:%(process)d] [%(funcName)s:%(lineno)d] %(message)s')
|
||||||
|
|
||||||
|
certicate = Certificate(openssl, workdir_cert_ca, workdir_cert_appli,
|
||||||
|
passca, passappli,
|
||||||
|
countryName,
|
||||||
|
stateOrProvinceName,
|
||||||
|
localityName,
|
||||||
|
organizationName,
|
||||||
|
commonName,
|
||||||
|
sizeCa,
|
||||||
|
sizeAppli ,
|
||||||
|
sizeChild)
|
||||||
|
logging.info("Generate CA certificate")
|
||||||
|
certicate.createCACertificate()
|
||||||
|
logging.info("Generate Application certificate")
|
||||||
|
certicate.createApplicationCertificate()
|
||||||
|
logging.info("Generate Server certificate")
|
||||||
|
certicate.createChildCertificate('server', 'server_cert')
|
||||||
|
logging.info("Generate Client certificate")
|
||||||
|
certicate.createChildCertificate('client', 'client_cert')
|
||||||
|
logging.info("Certifcate generated")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='Create certificate')
|
||||||
|
parser.add_argument('--version', action='version', version='%(prog)s 1.0')
|
||||||
|
parser.add_argument( '--openssl', default='openssl', help='binary openssl')
|
||||||
|
parser.add_argument('-c', '--workdir-cert-ca', default='ca', help='workdir certificate CA')
|
||||||
|
parser.add_argument('-a', '--workdir-cert-appli', default='ca/appli', help='workdir certificate Application')
|
||||||
|
parser.add_argument( '--show-log-console', action='store_true',
|
||||||
|
help='show message in console', default=False)
|
||||||
|
parser.add_argument('--filelog', type=argparse.FileType('wt'),
|
||||||
|
default=None, help='log file')
|
||||||
|
parser.add_argument('--log',
|
||||||
|
default='INFO', help='log level [DEBUG, INFO, WARNING, ERROR')
|
||||||
|
parser.add_argument('--sizeCa', type=int, default=4096, help='Define size key for CA certificate')
|
||||||
|
parser.add_argument('--sizeAppli', type=int, default=4096, help='Define size key for Application certificate')
|
||||||
|
parser.add_argument('--sizeChild', type=int, default=4096, help='Define size key for Child certificate')
|
||||||
|
parser.add_argument('--passca', default='OpenNelCA9439', help='define password for CA certificate')
|
||||||
|
parser.add_argument('--passappli', default='OpenNelAPPLI1097', help='define password for Application certificate')
|
||||||
|
parser.add_argument('--countryName', default='FR', help='countryName for certicate')
|
||||||
|
parser.add_argument('--stateOrProvinceName', default='France', help='stateOrProvinceName for certicate')
|
||||||
|
parser.add_argument('--localityName', default='Paris', help='localityName for certicate')
|
||||||
|
parser.add_argument('--organizationName', default='khanat', help='organizationName for certicate')
|
||||||
|
parser.add_argument('--commonName', default='khanat', help='commonName for certicate')
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(fileLog = args.filelog,
|
||||||
|
logLevel = args.log,
|
||||||
|
show_log_console = args.show_log_console,
|
||||||
|
workdir_cert_ca = args.workdir_cert_ca,
|
||||||
|
workdir_cert_appli = args.workdir_cert_appli,
|
||||||
|
openssl = args.openssl,
|
||||||
|
sizeCa = args.sizeCa,
|
||||||
|
sizeAppli = args.sizeAppli,
|
||||||
|
sizeChild = args.sizeChild,
|
||||||
|
passca = args.passca,
|
||||||
|
passappli = args.passappli,
|
||||||
|
countryName = args.countryName,
|
||||||
|
stateOrProvinceName = args.stateOrProvinceName,
|
||||||
|
localityName = args.localityName,
|
||||||
|
organizationName = args.organizationName,
|
||||||
|
commonName = args.commonName)
|
|
@ -21,7 +21,7 @@
|
||||||
# Global parameter
|
# Global parameter
|
||||||
##############################
|
##############################
|
||||||
##############################
|
##############################
|
||||||
[config]
|
[manage]
|
||||||
# Define port listen (default 8000)
|
# Define port listen (default 8000)
|
||||||
port = 8000
|
port = 8000
|
||||||
|
|
||||||
|
@ -29,10 +29,13 @@ port = 8000
|
||||||
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
||||||
|
|
||||||
# key
|
# key
|
||||||
keyfile = /home/gameserver/khanat/key.pem
|
keyfile = /home/gameserver/ca/appli/private/serverkey.pem
|
||||||
|
|
||||||
# certificate
|
# certificate
|
||||||
certfile = /home/gameserver/khanat/cert.pem
|
certfile = /home/gameserver/ca/appli/certs/servercert.pem
|
||||||
|
|
||||||
|
# certification to check signature
|
||||||
|
ca_cert = /home/gameserver/ca/appli/certs/cachaincert.pem
|
||||||
|
|
||||||
# address listen (default all port)
|
# address listen (default all port)
|
||||||
address =
|
address =
|
||||||
|
|
|
@ -43,19 +43,22 @@ Design
|
||||||
|
|
||||||
Configuration File : This script need configuration file (see below for model)
|
Configuration File : This script need configuration file (see below for model)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
[config]
|
[manager]
|
||||||
# Define port listen (default 8000)
|
# Define port listen (default 8000)
|
||||||
port = 8000
|
port = 8000
|
||||||
|
|
||||||
# Generate key
|
# Generate key
|
||||||
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
||||||
|
|
||||||
# key
|
# your key
|
||||||
keyfile = crt/key.pem
|
keyfile = crt/key.pem
|
||||||
|
|
||||||
# certificate
|
# your certificate
|
||||||
certfile = crt/cert.pem
|
certfile = crt/cert.pem
|
||||||
|
|
||||||
|
# certification to check signature
|
||||||
|
ca_cert = /home/gameserver/ca/appli/certs/cachaincert.pem
|
||||||
|
|
||||||
# address listen (default all port)
|
# address listen (default all port)
|
||||||
address =
|
address =
|
||||||
|
|
||||||
|
@ -401,14 +404,15 @@ class ServerHttp(multiprocessing.Process):
|
||||||
Initialize server HTTPS
|
Initialize server HTTPS
|
||||||
* define Dictionnary queueIn & queueOut (with key as section's name in configuration)
|
* define Dictionnary queueIn & queueOut (with key as section's name in configuration)
|
||||||
"""
|
"""
|
||||||
def __init__(self, keyfile, certfile, address = '', port=8000):
|
def __init__(self, keyfile, certfile, ca_cert, address = '', port=8000):
|
||||||
multiprocessing.Process.__init__(self)
|
multiprocessing.Process.__init__(self)
|
||||||
self.listQueueIn = {}
|
self.listQueueIn = {}
|
||||||
self.listQueueOut = {}
|
self.listQueueOut = {}
|
||||||
self.listEvent = {}
|
self.listEvent = {}
|
||||||
self.port = port
|
self.port = port
|
||||||
self.keyfile = keyfile
|
self.key_file = keyfile
|
||||||
self.certfile = certfile
|
self.cert_file = certfile
|
||||||
|
self.ca_cert = ca_cert
|
||||||
self.address = address
|
self.address = address
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -418,11 +422,20 @@ class ServerHttp(multiprocessing.Process):
|
||||||
self.listEvent,
|
self.listEvent,
|
||||||
server_address,
|
server_address,
|
||||||
ManageHttpRequest)
|
ManageHttpRequest)
|
||||||
httpd.socket = ssl.wrap_socket (httpd.socket,
|
if self.ca_cert:
|
||||||
keyfile = self.keyfile,
|
httpd.socket = ssl.wrap_socket(httpd.socket,
|
||||||
certfile = self.certfile,
|
keyfile = self.key_file,
|
||||||
ca_certs=None,
|
certfile = self.cert_file,
|
||||||
|
ca_certs = self.ca_cert,
|
||||||
|
cert_reqs = ssl.CERT_REQUIRED,
|
||||||
|
ssl_version=ssl.PROTOCOL_TLSv1_2,
|
||||||
server_side = True)
|
server_side = True)
|
||||||
|
else:
|
||||||
|
httpd.socket = ssl.wrap_socket (httpd.socket,
|
||||||
|
keyfile = self.key_file,
|
||||||
|
certfile = self.cert_file,
|
||||||
|
server_side = True)
|
||||||
|
logging.info('https listen')
|
||||||
httpd.serve_forever()
|
httpd.serve_forever()
|
||||||
|
|
||||||
def append(self, name, queueIn, queueOut, event):
|
def append(self, name, queueIn, queueOut, event):
|
||||||
|
@ -460,9 +473,19 @@ class ManageCommand():
|
||||||
""" Thread to read output (stdout) """
|
""" Thread to read output (stdout) """
|
||||||
fl = fcntl.fcntl(self.process.stdout, fcntl.F_GETFL)
|
fl = fcntl.fcntl(self.process.stdout, fcntl.F_GETFL)
|
||||||
fcntl.fcntl(self.process.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
fcntl.fcntl(self.process.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
||||||
logging.debug("Start reader %s " % self.name)
|
logging.debug("Start reader %s" % self.name)
|
||||||
while self.eventRunning.is_set():
|
while self.eventRunning.is_set():
|
||||||
|
code = self.process.poll()
|
||||||
|
if code is not None:
|
||||||
|
logging.error("process %s down" % self.name)
|
||||||
|
self.eventRunning.clear()
|
||||||
|
continue
|
||||||
|
try:
|
||||||
line = self.process.stdout.readline()
|
line = self.process.stdout.readline()
|
||||||
|
except AttributeError:
|
||||||
|
logging.error("process %s down (not detected)" % self.name)
|
||||||
|
self.eventRunning.clear()
|
||||||
|
continue
|
||||||
if not line:
|
if not line:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
continue
|
continue
|
||||||
|
@ -676,21 +699,25 @@ class Manager():
|
||||||
if name == 'config':
|
if name == 'config':
|
||||||
logging.debug("read config '%s'" % name)
|
logging.debug("read config '%s'" % name)
|
||||||
try:
|
try:
|
||||||
port = int(config[name]['port'])
|
self.port = int(config[name]['port'])
|
||||||
except (TypeError, KeyError, ValueError):
|
except (TypeError, KeyError, ValueError):
|
||||||
port = 8000
|
self.port = 8000
|
||||||
try:
|
try:
|
||||||
address = config[name]['address']
|
self.address = config[name]['address']
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
address = ''
|
self.address = ''
|
||||||
try:
|
try:
|
||||||
keyfile = config[name]['keyfile']
|
self.keyfile = config[name]['keyfile']
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
keyfile = 'crt/key.pem'
|
self.keyfile = 'crt/key.pem'
|
||||||
try:
|
try:
|
||||||
certfile = config[name]['certfile']
|
self.certfile = config[name]['certfile']
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
certfile = 'crt/cert.pem'
|
self.certfile = 'crt/cert.pem'
|
||||||
|
try:
|
||||||
|
self.ca_cert = config[name]['ca_cert']
|
||||||
|
except (TypeError, KeyError):
|
||||||
|
self.ca_cert = 'crt/ca_cert.crt'
|
||||||
elif 'command' in config[name]:
|
elif 'command' in config[name]:
|
||||||
logging.debug("read command '%s'" % name)
|
logging.debug("read command '%s'" % name)
|
||||||
if 'path' in config[name]:
|
if 'path' in config[name]:
|
||||||
|
@ -715,7 +742,7 @@ class Manager():
|
||||||
bufsize = 100
|
bufsize = 100
|
||||||
self.param.setdefault(name, {'command': config[name]['command'], 'path': path, 'logsize': logsize, 'bufsize': bufsize})
|
self.param.setdefault(name, {'command': config[name]['command'], 'path': path, 'logsize': logsize, 'bufsize': bufsize})
|
||||||
|
|
||||||
self.serverHttp = ServerHttp(keyfile, certfile, address, port)
|
self.serverHttp = ServerHttp(self.keyfile, self.certfile, self.ca_cert, self.address, self.port)
|
||||||
if filecfg is None:
|
if filecfg is None:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
|
@ -29,10 +29,13 @@ port = 8000
|
||||||
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
# openssl req -nodes -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj "/C=FR/ST=France/L=Paris/O=khaganat/CN=khaganat.org"
|
||||||
|
|
||||||
# key
|
# key
|
||||||
keyfile = /home/gameserver/khanat/key.pem
|
keyfile = /home/gameserver/ca/appli/private/serverkey.pem
|
||||||
|
|
||||||
# certificate
|
# certificate
|
||||||
certfile = /home/gameserver/khanat/cert.pem
|
certfile = /home/gameserver/ca/appli/certs/servercert.pem
|
||||||
|
|
||||||
|
# certification to check signature
|
||||||
|
ca_cert = /home/gameserver/ca/appli/certs/cachaincert.pem
|
||||||
|
|
||||||
# address listen (default all port)
|
# address listen (default all port)
|
||||||
address =
|
address =
|
||||||
|
|
Loading…
Reference in a new issue