[REF] Split in modules

This commit is contained in:
Kevin Guerineau
2024-05-10 16:47:51 +02:00
parent 3629011913
commit ce28001bae
6 changed files with 429 additions and 361 deletions
-353
View File
@@ -125,356 +125,3 @@ def check_directories(path,verbose=False):
with open(os.path.join(path,'index.txt'),'w') as file:
pass
def create_openssl_config(force=False,verbose=False):
if force:
Printing.error("Do you realy want to remove ALL you PKI ? This will destroy ALL YOUR CERTIFICATES AND PRIVATE KEY")
Printing.error("After that, you MUST REGENERATE YOUR PKI with NEW certificates and private key for ALL YOUR DOMAIN CONTROLLERS AND USERS")
destroy = input('If you are realy sure, please enter : "I want to remove all my PKI" : ')
if destroy == 'I want to remove all my PKI':
Printing.information('OK, too late ! Destroying your PKI !')
time.sleep(1)
shutil.rmtree(TisPKI.pki_dir(), ignore_errors=True)
Printing.information('Check Root CA OpenSSL Config')
if config.get('general','pki_dir'):
check_directories(path=config.get('general','pki_dir'),verbose=verbose)
else:
Printing.error('No pki_dir set in samba-pki-tools.ini')
sys.exit(1)
root_ca_config = os.path.join(TisPKI.pki_dir(),'config','openssl_root_ca.ini')
if not os.path.isfile(root_ca_config):
Printing.information('Root CA OpenSSL configfile not exist. Creating...')
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
root_ca_tmpl = jinja_env.get_template('openssl_root_ca.tmpl')
root_ca_tmpl_var = {
'organization_ou': config.get('openssl_config','organization_name') + ' CA',
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'default_crl_duration' : config.get('openssl_config','default_crl_duration'),
'pki_dir': TisPKI.pki_dir(),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'organization_cn': config.get('openssl_config','organization_cn'),
'crl_uri': config.get('openssl_config','crl_uri')
}
config_string = root_ca_tmpl.render(root_ca_tmpl_var)
with open(root_ca_config,'wt') as file:
file.write(config_string)
if os.path.isfile(root_ca_config):
Printing.success('Root CA OpenSSL config file is correctly generated !')
else:
Printing.warning('Root CA OpenSSL config already exist. Skip.')
# Generate privkey and cert for Root CA
if not os.path.isfile(TisPKI.root_ca_keyfile()) or not os.path.isfile(TisPKI.root_ca_certfile()):
Printing.information('Generate Root CA private key')
gen_root_ca = subprocess.run(f'/usr/bin/openssl req -x509 -new -sha512 -config {root_ca_config} \
-days 3650 -extensions v3_ca -keyout {TisPKI.root_ca_keyfile()} -out {TisPKI.root_ca_certfile()}',
shell=True, check=False, executable='/bin/bash')
if gen_root_ca.returncode == 0:
if verbose:
subprocess.run(f'openssl x509 -in {TisPKI.root_ca_certfile()} -text', shell=True, check=True, executable='/bin/bash')
Printing.information(f'Root CA Certfile is stored in {TisPKI.root_ca_certfile()}')
else:
Printing.error('Error on generating Root CA private key')
os.remove(TisPKI.root_ca_keyfile())
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
create_openssl_config(force,verbose)
else:
Printing.warning('Root CA private key and certificate already exist. Skip.')
def create_openssl_intermediate(name, force=False,verbose=False):
## if force:
## Printing.error("Do you realy want to remove ALL you PKI ? This will destroy ALL YOUR CERTIFICATES AND PRIVATE KEY")
## Printing.error("After that, you MUST REGENERATE YOUR PKI with NEW certificates and private key for ALL YOUR DOMAIN CONTROLLERS AND USERS")
## destroy = input('If you are realy sure, please enter : "I want to remove all my PKI" : ')
## if destroy == 'I want to remove all my PKI':
## Printing.information('OK, too late ! Destroying your PKI !')
## time.sleep(1)
## shutil.rmtree(TisPKI.pki_dir(), ignore_errors=True)
Printing.information(f'Create intermediate CA {name} ')
check_directories(path=TisPKI.pki_intermediate_dir(name),verbose=verbose)
intermediate_ca_config = os.path.join(TisPKI.intermediate_config_path(name),'create_intermediate_ca.ini')
intermediate_crl_file = os.path.join(TisPKI.intermediate_crl_path(name),f'{name}_intermediate_ca.crl')
root_ca_sign_intermediate = os.path.join(TisPKI.root_config_path(),'openssl_root_ca_sign_intermediate.ini')
if not os.path.isfile(root_ca_sign_intermediate):
if TisPKI.intermediate_ca:
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
root_ca_tmpl = jinja_env.get_template('openssl_sign_intermediate_csr.tmpl')
root_ca_tmpl_var = {
'organization_ou': config.get('openssl_config','organization_name') + ' CA',
'pki_dir': TisPKI.pki_dir(),
'root_ca_keyfile': TisPKI.root_ca_keyfile(),
'root_ca_certfile': TisPKI.root_ca_certfile(),
'intermediate_crl_uri': config.get('openssl_config','intermediate_crl_uri'),
'default_crl_duration' : config.get('openssl_config','default_crl_duration'),
}
config_string = root_ca_tmpl.render(root_ca_tmpl_var)
with open(root_ca_sign_intermediate,'wt') as file:
file.write(config_string)
if os.path.isfile(root_ca_sign_intermediate):
Printing.success('Root CA OpenSSL sign intermediate config file is correctly generated !')
if not os.path.isfile(intermediate_ca_config):
Printing.information('Intermediate CA OpenSSL configfile not exist. Creating...')
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
intermediate_ca_tmpl = jinja_env.get_template('openssl_create_intermediate_ca.tmpl')
intermediate_ca_tmpl_var = {
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'intermediate_organization_cn': name,
'intermediate_crl_uri': config.get('openssl_config','intermediate_crl_uri')
}
config_string = intermediate_ca_tmpl.render(intermediate_ca_tmpl_var)
with open(intermediate_ca_config,'wt') as file:
file.write(config_string)
if os.path.isfile(intermediate_ca_config):
Printing.success('Intermediate CA OpenSSL configfile is correctly generated !')
else:
Printing.information('Intermediate CA OpenSSL config already exist. Skip.')
if not os.path.isfile(TisPKI.intermediate_ca_keyfile(name)) and not os.path.isfile(TisPKI.intermediate_ca_certfile(name)):
Printing.information('Generate Intermediate CA private key and CSR')
gen_intermediate_ca = subprocess.run(f"/usr/bin/openssl req -config {intermediate_ca_config} -new -sha512 -keyout {TisPKI.intermediate_ca_keyfile(name)} \
-out {TisPKI.intermediate_csr_path(name)}/{name.replace(' ','_')}_intermediate_ca.csr", shell=True, check=False, executable='/bin/bash')
if gen_intermediate_ca.returncode == 0:
Printing.information('Sign Intermediate CA with Root CA')
sign_intermediate_ca = subprocess.run(f"/usr/bin/openssl ca -config {os.path.join(TisPKI.root_config_path(),'openssl_root_ca_sign_intermediate.ini')} \
-extensions v3_intermediate_ca -days 1825 -notext -md sha512 -create_serial -in {TisPKI.intermediate_csr_path(name)}/{name.replace(' ','_')}_intermediate_ca.csr \
-out {TisPKI.intermediate_ca_certfile(name)}", shell=True, check=False, executable='/bin/bash')
if sign_intermediate_ca.returncode == 0:
if verbose:
subprocess.run(f'openssl x509 -in {TisPKI.intermediate_ca_certfile(name)} -text', shell=True, check=True, executable='/bin/bash')
Printing.success(f'Intermediate CA Certfile is stored in : {TisPKI.intermediate_ca_certfile(name)}')
else:
Printing.error('Error on generating Intermediate CA private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(TisPKI.intermediate_ca_keyfile(name))
create_openssl_intermediate(name, force, verbose)
else:
Printing.error('Error on generating Intermediate CA private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(TisPKI.intermediate_ca_keyfile(name))
create_openssl_intermediate(name, force, verbose)
else:
Printing.warning('Intermediate CA private key and certificate already exist. Skip.')
def generate_dc_certificate(dc_name=None, ca_name=None, force=False, verbose=False):
if ca_name != "Root":
dc_certfile = os.path.join(TisPKI.intermediate_cert_path(ca_name),f'{dc_name}.crt')
dc_keyfile = os.path.join(TisPKI.intermediate_keyout_path(ca_name),f'{dc_name}.key')
dc_csrfile = os.path.join(TisPKI.intermediate_csr_path(ca_name),f'{dc_name}.csr')
dc_openssl_configfile = os.path.join(TisPKI.intermediate_config_path(ca_name),f'openssl_{dc_name}.ini')
crl_file = os.path.join(TisPKI.intermediate_crl_path(ca_name),'intermediate_ca.crl')
dc_ca_keyfile = TisPKI.intermediate_ca_keyfile(ca_name)
dc_ca_certfile = TisPKI.intermediate_ca_certfile(ca_name)
crl_uri = config.get('openssl_config','intermediate_crl_uri')
pki_dir = TisPKI.pki_intermediate_dir(ca_name)
else:
dc_certfile = os.path.join(TisPKI.root_cert_path(),f'{dc_name}.crt')
dc_keyfile = os.path.join(TisPKI.root_keyout_path(),f'{dc_name}.key')
dc_csrfile = os.path.join(TisPKI.root_csr_path(),f'{dc_name}.csr')
dc_openssl_configfile = os.path.join(TisPKI.root_config_path(),f'openssl_{dc_name}.ini')
crl_file = os.path.join(TisPKI.root_crl_path(),'root_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.root_keyout_path(),'root_ca.key')
dc_ca_certfile = os.path.join(TisPKI.root_cert_path(),'root_ca.crt')
crl_uri = config.get('openssl_config','crl_uri')
pki_dir = TisPKI.pki_dir()
if not os.path.isfile(dc_certfile) and not os.path.isfile(dc_keyfile):
Printing.information(f'Generate certificate for {dc_name}')
dc_guid = subprocess.run('/bin/bash get_guid.sh',shell=True, check=True, executable='/bin/bash')
if dc_guid.returncode != 0:
Printing.error('Unable to find dc_guid')
sys.exit(1)
else:
dc_name_guid = dc_name.split('.')[0]
dc_guid = str(subprocess.check_output(f'/bin/bash get_guid.sh {dc_name_guid}',shell=True).decode("utf-8")).strip()
if verbose:
Printing.information(f'{dc_name} GUID is : ' + str(dc_guid).strip())
template_dir = ('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
dc_tmpl = jinja_env.get_template('openssl_server_cert.tmpl')
dc_tmpl_var = {
'dc_name': dc_name,
'dc_guid': str(dc_guid),
'crl_uri': crl_uri,
'pki_dir': pki_dir,
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'dc_ca_keyfile': dc_ca_keyfile,
'dc_ca_certfile': dc_ca_certfile,
'commonName': dc_name
}
config_string = dc_tmpl.render(dc_tmpl_var)
with open(dc_openssl_configfile,'wt') as file:
file.write(config_string)
if os.path.isfile(dc_openssl_configfile):
Printing.information(f'{dc_name} OpenSSL configfile is correctly generated !')
Printing.information(f'Generate private key and CSR for {dc_name}')
gen_dc_key = subprocess.run(f"openssl req -new -addext 'subjectAltName = email:copy' -newkey rsa:4096 -keyout {dc_keyfile} \
-out {dc_csrfile} -config {dc_openssl_configfile}" , shell=True, check=False, executable='/bin/bash')
if gen_dc_key.returncode == 0:
if os.path.isfile(dc_csrfile):
Printing.information(f'Sign certificate for {dc_name}')
sign_dc_cert = subprocess.run(f'openssl ca -config {dc_openssl_configfile} -extensions usr_cert_mskdc \
-days 3650 -notext -md sha512 -create_serial -in {dc_csrfile} -out {dc_certfile}', shell=True, check=False, executable='/bin/bash')
if sign_dc_cert.returncode == 0:
if os.path.isfile(dc_certfile):
print('Concatenation of DC and intermediate cert')
subprocess.run(f'cat {dc_certfile} {dc_ca_certfile} > {dc_certfile}_full',shell=True)
Printing.success(f'Certificat is stored in : {dc_certfile}')
Printing.success(f'Key is stored in : {dc_keyfile}')
else:
Printing.error('Error on sign Domain Controler certificate')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(dc_keyfile)
generate_dc_certificate(dc_name, ca_name, force, verbose)
else:
Printing.error('Error on generating Domain Controler private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(dc_keyfile)
generate_dc_certificate(dc_name, ca_name, force, verbose)
def generate_user_certificate():
default_bits_user = config.get('openssl_config','default_bits_user')
username = input('Enter username')
upn_suffix = config.get('samba_ad','upn_suffix')
upn = f'{username}@{upn_suffix}'
if TisPKI.intermediate_ca:
crl_file = os.path.join(TisPKI.intermediate_crl_path(),'intermediate_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.intermediate_keyout_path(),'intermediate_ca.key')
dc_ca_certfile = os.path.join(TisPKI.intermediate_cert_path(),'intermediate_ca.crt')
crl_uri = config.get('openssl_config','intermediate_crl_uri')
pki_dir = TisPKI.pki_intermediate_dir()
openssl_user_file = os.path.join(TisPKI.intermediate_config_path(),'openssl_user.ini')
emailAddress = upn
commonName = username
else:
crl_file = os.path.join(TisPKI.root_crl_path(),'root_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.root_keyout_path(),'root_ca.key')
dc_ca_certfile = os.path.join(TisPKI.root_cert_path(),'root_ca.crt')
crl_uri = config.get('openssl_config','crl_uri')
pki_dir = TisPKI.pki_dir()
openssl_user_file = os.path.join(TisPKI.root_config_path(),'openssl_user.ini')
emailAddress = upn
commonName = username
template_dir = ('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
user_tmpl = jinja_env.get_template('openssl_user_cert.tmpl')
user_tmpl_var = {
'crl_uri': crl_uri,
'pki_dir': pki_dir,
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'dc_ca_keyfile': dc_ca_keyfile,
'dc_ca_certfile': dc_ca_certfile,
'default_bits_user': config.get('openssl_config','default_bits_user'),
'emailAddress' : emailAddress,
'commonName' : commonName
}
config_string = user_tmpl.render(user_tmpl_var)
with open(openssl_user_file,'wt') as file:
file.write(config_string)
if os.path.isfile(openssl_user_file):
print(f'User OpenSSL configfile is correctly generated !')
print(f'Generate private key for {upn}')
print(subprocess.run(f"openssl req -new -newkey rsa:{default_bits_user} -keyout {TisPKI.root_keyout_path()}/{username}.key -out {TisPKI.root_csr_path()}/{username}.csr -config <(cat {openssl_user_file} <(cat <<-EOF\n[ sanuser ]\notherName=msUPN;UTF8:{upn}\nemail=copy\nEOF\n)\n)",shell=True,check=True, executable='/bin/bash'))
print(f'Sign certificate')
print(subprocess.run(f'openssl ca -extensions usr_cert_scarduser -days 730 -notext -md sha512 -create_serial -in {TisPKI.root_csr_path()}/{username}.csr -out {TisPKI.root_cert_path()}/{username}.crt -config <(cat {openssl_user_file} <(cat <<-EOF\n[ sanuser ]\notherName=msUPN;UTF8:{upn}\nemail=copy\nEOF\n)\n)',shell=True,check=True, executable='/bin/bash'))
print('Remove password in rsa key')
print(subprocess.run(f'openssl rsa -in {TisPKI.root_keyout_path()}/{username}.key -out {TisPKI.root_keyout_path()}/{username}-nopasswd.key',shell=True,check=True, executable='/bin/bash'))
print('Create p12')
print(subprocess.run(f'openssl pkcs12 -export -inkey {TisPKI.root_keyout_path()}/{username}-nopasswd.key -in {TisPKI.root_cert_path()}/{username}.crt -out {TisPKI.root_p12_path()}/{username}.p12', shell=True,check=True, executable='/bin/bash'))
def main():
if config.get('general','pki_dir'):
check_directories(root_path=config.get('general','pki_dir'))
else:
print('No pki_dir set in samba-pki-tools.ini')
sys.exit(1)
if config.get('openssl_config','root_name'):
create_openssl_config()
else:
print('No root_name set in samba-pki-tools.ini')
sys.exit(1)
if config.getboolean('openssl_config','create_intermediate'):
create_openssl_intermediate()
if config.get('samba_ad','dc_list'):
generate_dc_certificate()
else:
print('No dc_list set in samba-pki-tools.ini')
sys.exit(1)
generate_user_certificate()
if __name__ == '__main__':
main()
+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/python3
#-------------------------------------------------------------------------------
# Name: Samba PKI Tools
# Purpose:
#
# Author: kguerineau-adm
#
# Created: 10/05/2024
# Copyright: (c) kguerineau-adm 2024
# Licence: <your licence>
#-------------------------------------------------------------------------------
# Maange DC Certificates
from common import Printing, TisPKI, check_directories
import subprocess
import jinja2
import os
import configparser
import sys
from colorama import Fore, Style
import shutil
import time
def generate_dc_certificate(dc_name=None, ca_name=None, force=False, verbose=False):
if ca_name != "Root":
dc_certfile = os.path.join(TisPKI.intermediate_cert_path(ca_name),f'{dc_name}.crt')
dc_keyfile = os.path.join(TisPKI.intermediate_keyout_path(ca_name),f'{dc_name}.key')
dc_csrfile = os.path.join(TisPKI.intermediate_csr_path(ca_name),f'{dc_name}.csr')
dc_openssl_configfile = os.path.join(TisPKI.intermediate_config_path(ca_name),f'openssl_{dc_name}.ini')
crl_file = os.path.join(TisPKI.intermediate_crl_path(ca_name),'intermediate_ca.crl')
dc_ca_keyfile = TisPKI.intermediate_ca_keyfile(ca_name)
dc_ca_certfile = TisPKI.intermediate_ca_certfile(ca_name)
crl_uri = config.get('openssl_config','intermediate_crl_uri')
pki_dir = TisPKI.pki_intermediate_dir(ca_name)
else:
dc_certfile = os.path.join(TisPKI.root_cert_path(),f'{dc_name}.crt')
dc_keyfile = os.path.join(TisPKI.root_keyout_path(),f'{dc_name}.key')
dc_csrfile = os.path.join(TisPKI.root_csr_path(),f'{dc_name}.csr')
dc_openssl_configfile = os.path.join(TisPKI.root_config_path(),f'openssl_{dc_name}.ini')
crl_file = os.path.join(TisPKI.root_crl_path(),'root_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.root_keyout_path(),'root_ca.key')
dc_ca_certfile = os.path.join(TisPKI.root_cert_path(),'root_ca.crt')
crl_uri = config.get('openssl_config','crl_uri')
pki_dir = TisPKI.pki_dir()
if not os.path.isfile(dc_certfile) and not os.path.isfile(dc_keyfile):
Printing.information(f'Generate certificate for {dc_name}')
dc_guid = subprocess.run('/bin/bash get_guid.sh',shell=True, check=True, executable='/bin/bash')
if dc_guid.returncode != 0:
Printing.error('Unable to find dc_guid')
sys.exit(1)
else:
dc_name_guid = dc_name.split('.')[0]
dc_guid = str(subprocess.check_output(f'/bin/bash get_guid.sh {dc_name_guid}',shell=True).decode("utf-8")).strip()
if verbose:
Printing.information(f'{dc_name} GUID is : ' + str(dc_guid).strip())
template_dir = ('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
dc_tmpl = jinja_env.get_template('openssl_server_cert.tmpl')
dc_tmpl_var = {
'dc_name': dc_name,
'dc_guid': str(dc_guid),
'crl_uri': crl_uri,
'pki_dir': pki_dir,
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'dc_ca_keyfile': dc_ca_keyfile,
'dc_ca_certfile': dc_ca_certfile,
'commonName': dc_name
}
config_string = dc_tmpl.render(dc_tmpl_var)
with open(dc_openssl_configfile,'wt') as file:
file.write(config_string)
if os.path.isfile(dc_openssl_configfile):
Printing.information(f'{dc_name} OpenSSL configfile is correctly generated !')
Printing.information(f'Generate private key and CSR for {dc_name}')
gen_dc_key = subprocess.run(f"openssl req -new -addext 'subjectAltName = email:copy' -newkey rsa:4096 -keyout {dc_keyfile} \
-out {dc_csrfile} -config {dc_openssl_configfile}" , shell=True, check=False, executable='/bin/bash')
if gen_dc_key.returncode == 0:
if os.path.isfile(dc_csrfile):
Printing.information(f'Sign certificate for {dc_name}')
sign_dc_cert = subprocess.run(f'openssl ca -config {dc_openssl_configfile} -extensions usr_cert_mskdc \
-days 3650 -notext -md sha512 -create_serial -in {dc_csrfile} -out {dc_certfile}', shell=True, check=False, executable='/bin/bash')
if sign_dc_cert.returncode == 0:
if os.path.isfile(dc_certfile):
print('Concatenation of DC and intermediate cert')
subprocess.run(f'cat {dc_certfile} {dc_ca_certfile} > {dc_certfile}_full',shell=True)
Printing.success(f'Certificat is stored in : {dc_certfile}')
Printing.success(f'Key is stored in : {dc_keyfile}')
else:
Printing.error('Error on sign Domain Controler certificate')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(dc_keyfile)
generate_dc_certificate(dc_name, ca_name, force, verbose)
else:
Printing.error('Error on generating Domain Controler private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(dc_keyfile)
generate_dc_certificate(dc_name, ca_name, force, verbose)
+116
View File
@@ -0,0 +1,116 @@
#!/usr/bin/python3
#-------------------------------------------------------------------------------
# Name: Samba PKI Tools
# Purpose:
#
# Author: kguerineau-adm
#
# Created: 10/05/2024
# Copyright: (c) kguerineau-adm 2024
# Licence: <your licence>
#-------------------------------------------------------------------------------
# Maange Intermediate CA
from common import Printing, TisPKI, check_directories
import subprocess
import jinja2
import os
import configparser
import sys
from colorama import Fore, Style
import shutil
import time
def create_openssl_intermediate(name, force=False,verbose=False):
## if force:
## Printing.error("Do you realy want to remove ALL you PKI ? This will destroy ALL YOUR CERTIFICATES AND PRIVATE KEY")
## Printing.error("After that, you MUST REGENERATE YOUR PKI with NEW certificates and private key for ALL YOUR DOMAIN CONTROLLERS AND USERS")
## destroy = input('If you are realy sure, please enter : "I want to remove all my PKI" : ')
## if destroy == 'I want to remove all my PKI':
## Printing.information('OK, too late ! Destroying your PKI !')
## time.sleep(1)
## shutil.rmtree(TisPKI.pki_dir(), ignore_errors=True)
Printing.information(f'Create intermediate CA {name}')
check_directories(path=TisPKI.pki_intermediate_dir(name),verbose=verbose)
intermediate_ca_config = os.path.join(TisPKI.intermediate_config_path(name),'create_intermediate_ca.ini')
intermediate_crl_file = os.path.join(TisPKI.intermediate_crl_path(name),f'{name}_intermediate_ca.crl')
root_ca_sign_intermediate = os.path.join(TisPKI.root_config_path(),'openssl_root_ca_sign_intermediate.ini')
if not os.path.isfile(root_ca_sign_intermediate):
if TisPKI.intermediate_ca:
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
root_ca_tmpl = jinja_env.get_template('openssl_sign_intermediate_csr.tmpl')
root_ca_tmpl_var = {
'organization_ou': config.get('openssl_config','organization_name') + ' CA',
'pki_dir': TisPKI.pki_dir(),
'root_ca_keyfile': TisPKI.root_ca_keyfile(),
'root_ca_certfile': TisPKI.root_ca_certfile(),
'intermediate_crl_uri': config.get('openssl_config','intermediate_crl_uri'),
'default_crl_duration' : config.get('openssl_config','default_crl_duration'),
}
config_string = root_ca_tmpl.render(root_ca_tmpl_var)
with open(root_ca_sign_intermediate,'wt') as file:
file.write(config_string)
if os.path.isfile(root_ca_sign_intermediate):
Printing.success('Root CA OpenSSL sign intermediate config file is correctly generated !')
if not os.path.isfile(intermediate_ca_config):
Printing.information('Intermediate CA OpenSSL configfile not exist. Creating...')
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
intermediate_ca_tmpl = jinja_env.get_template('openssl_create_intermediate_ca.tmpl')
intermediate_ca_tmpl_var = {
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'intermediate_organization_cn': name,
'intermediate_crl_uri': config.get('openssl_config','intermediate_crl_uri')
}
config_string = intermediate_ca_tmpl.render(intermediate_ca_tmpl_var)
with open(intermediate_ca_config,'wt') as file:
file.write(config_string)
if os.path.isfile(intermediate_ca_config):
Printing.success('Intermediate CA OpenSSL configfile is correctly generated !')
else:
Printing.information('Intermediate CA OpenSSL config already exist. Skip.')
if not os.path.isfile(TisPKI.intermediate_ca_keyfile(name)) and not os.path.isfile(TisPKI.intermediate_ca_certfile(name)):
Printing.information('Generate Intermediate CA private key and CSR')
gen_intermediate_ca = subprocess.run(f"/usr/bin/openssl req -config {intermediate_ca_config} -new -sha512 -keyout {TisPKI.intermediate_ca_keyfile(name)} \
-out {TisPKI.intermediate_csr_path(name)}/{name.replace(' ','_')}_intermediate_ca.csr", shell=True, check=False, executable='/bin/bash')
if gen_intermediate_ca.returncode == 0:
Printing.information('Sign Intermediate CA with Root CA')
sign_intermediate_ca = subprocess.run(f"/usr/bin/openssl ca -config {os.path.join(TisPKI.root_config_path(),'openssl_root_ca_sign_intermediate.ini')} \
-extensions v3_intermediate_ca -days 1825 -notext -md sha512 -create_serial -in {TisPKI.intermediate_csr_path(name)}/{name.replace(' ','_')}_intermediate_ca.csr \
-out {TisPKI.intermediate_ca_certfile(name)}", shell=True, check=False, executable='/bin/bash')
if sign_intermediate_ca.returncode == 0:
if verbose:
subprocess.run(f'openssl x509 -in {TisPKI.intermediate_ca_certfile(name)} -text', shell=True, check=True, executable='/bin/bash')
Printing.success(f'Intermediate CA Certfile is stored in : {TisPKI.intermediate_ca_certfile(name)}')
else:
Printing.error('Error on generating Intermediate CA private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(TisPKI.intermediate_ca_keyfile(name))
create_openssl_intermediate(name, force, verbose)
else:
Printing.error('Error on generating Intermediate CA private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(TisPKI.intermediate_ca_keyfile(name))
create_openssl_intermediate(name, force, verbose)
else:
Printing.warning('Intermediate CA private key and certificate already exist. Skip.')
+9 -8
View File
@@ -13,6 +13,10 @@ from optparse import OptionParser, OptionGroup
from argparse import ArgumentParser
from common import *
from root_module import *
from intermediate_module import *
from dc_module import *
from user_module import *
def main():
@@ -20,20 +24,17 @@ def main():
parser = ArgumentParser(prog='Samba PKI Tools',
description='Manage PKI for Samba')
create_group = parser.add_argument_group('Create options')
create_group.add_argument('--initialize', dest="initialize", action="store_true", help="Create PKI")
create_group.add_argument('--full-initialize', dest="full_initialize", action="store_true", help="Create Root CA, intermediate CA and DC certificate. Use --name and --dc-name")
create_group.add_argument('--create-intermediate', dest="create_intermediate", action="store_true", help="Create an intermediate CA. Specify name with --name option.")
create_group.add_argument('--create-dc-cert', dest="create_dc_cert", action="store_true", help="Create a certificat for a Domain Controler")
root_group = parser.add_argument_group('Root CA options')
root_group.add_argument('--create-root', dest="initialize", action="store_true", help="Create PKI")
root_group.add_argument('--full-create', dest="full_initialize", action="store_true", help="Create Root CA, intermediate CA and DC certificate. Use --name and --dc-name")
root_group.add_argument('--root-crl', dest='root_crl', help='Regenerate CRL for root CA')
root_group.add_argument('--root-show-certs','--root-show-certificates', dest="root_certs", help='List all certificates issues of root CA')
intermediate_group = parser.add_argument_group('Intermediate CA options', 'Manage intermediate CA')
intermediate_group.add_argument('--create-intermediate', dest="create_intermediate", action="store_true", help="Create an intermediate CA. Specify name with --name option.")
intermediate_group.add_argument('--name', dest='intermediate_name', help='Specify what intermediate CA to manage')
intermediate_group.add_argument('--crl', dest='intermediate_crl', help='Regenerate CRL for intermediate CA')
intermediate_group.add_argument('--show-certs', '--show-certificates', dest='intermediate_list', help='List all certificates issues of intermediate CA')
intermediate_group.add_argument('--crl', dest='intermediate_crl', help='Regenerate CRL for intermediate CA. Specify name with --name option.')
intermediate_group.add_argument('--show-certs', '--show-certificates', dest='intermediate_list', help='List all certificates issues of intermediate CA. Specify name with --name option.')
dc_cert = parser.add_argument_group('Domain Controler options', 'Manage DC certificates')
dc_cert.add_argument('--dc-cert', dest="dc_cert", action="store_true", help="Create a DC certificate. Specify intermediate CA name with --name option. \
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/python3
#-------------------------------------------------------------------------------
# Name: Samba PKI Tools
# Purpose:
#
# Author: kguerineau-adm
#
# Created: 10/05/2024
# Copyright: (c) kguerineau-adm 2024
# Licence: <your licence>
#-------------------------------------------------------------------------------
# Maange Root CA
from common import Printing, TisPKI, check_directories
import subprocess
import jinja2
import os
import configparser
import sys
from colorama import Fore, Style
import shutil
import time
def create_openssl_config(force=False,verbose=False):
if force:
Printing.error("Do you realy want to remove ALL you PKI ? This will destroy ALL YOUR CERTIFICATES AND PRIVATE KEY")
Printing.error("After that, you MUST REGENERATE YOUR PKI with NEW certificates and private key for ALL YOUR DOMAIN CONTROLLERS AND USERS")
destroy = input('If you are realy sure, please enter : "I want to remove all my PKI" : ')
if destroy == 'I want to remove all my PKI':
Printing.information('OK, too late ! Destroying your PKI !')
time.sleep(1)
shutil.rmtree(TisPKI.pki_dir(), ignore_errors=True)
Printing.information('Check Root CA OpenSSL Config')
if config.get('general','pki_dir'):
check_directories(path=config.get('general','pki_dir'),verbose=verbose)
else:
Printing.error('No pki_dir set in samba-pki-tools.ini')
sys.exit(1)
root_ca_config = os.path.join(TisPKI.pki_dir(),'config','openssl_root_ca.ini')
if not os.path.isfile(root_ca_config):
Printing.information('Root CA OpenSSL configfile not exist. Creating...')
template_dir = os.path.join('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
root_ca_tmpl = jinja_env.get_template('openssl_root_ca.tmpl')
root_ca_tmpl_var = {
'organization_ou': config.get('openssl_config','organization_name') + ' CA',
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'default_crl_duration' : config.get('openssl_config','default_crl_duration'),
'pki_dir': TisPKI.pki_dir(),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'organization_cn': config.get('openssl_config','organization_cn'),
'crl_uri': config.get('openssl_config','crl_uri')
}
config_string = root_ca_tmpl.render(root_ca_tmpl_var)
with open(root_ca_config,'wt') as file:
file.write(config_string)
if os.path.isfile(root_ca_config):
Printing.success('Root CA OpenSSL config file is correctly generated !')
else:
Printing.warning('Root CA OpenSSL config already exist. Skip.')
# Generate privkey and cert for Root CA
if not os.path.isfile(TisPKI.root_ca_keyfile()) or not os.path.isfile(TisPKI.root_ca_certfile()):
Printing.information('Generate Root CA private key')
gen_root_ca = subprocess.run(f'/usr/bin/openssl req -x509 -new -sha512 -config {root_ca_config} \
-days 3650 -extensions v3_ca -keyout {TisPKI.root_ca_keyfile()} -out {TisPKI.root_ca_certfile()}',
shell=True, check=False, executable='/bin/bash')
if gen_root_ca.returncode == 0:
if verbose:
subprocess.run(f'openssl x509 -in {TisPKI.root_ca_certfile()} -text', shell=True, check=True, executable='/bin/bash')
Printing.information(f'Root CA Certfile is stored in {TisPKI.root_ca_certfile()}')
else:
Printing.error('Error on generating Root CA private key')
retry = input('If you want to retry, press Y : ')
if retry == "y" or retry == 'Y':
os.remove(TisPKI.root_ca_keyfile())
create_openssl_config(force,verbose)
else:
Printing.warning('Root CA private key and certificate already exist. Skip.')
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/python3
#-------------------------------------------------------------------------------
# Name: Samba PKI Tools
# Purpose:
#
# Author: kguerineau-adm
#
# Created: 10/05/2024
# Copyright: (c) kguerineau-adm 2024
# Licence: <your licence>
#-------------------------------------------------------------------------------
# Maange Users Certificates
from common import Printing, TisPKI, check_directories
import subprocess
import jinja2
import os
import configparser
import sys
from colorama import Fore, Style
import shutil
import time
def generate_user_certificate():
default_bits_user = config.get('openssl_config','default_bits_user')
username = input('Enter username')
upn_suffix = config.get('samba_ad','upn_suffix')
upn = f'{username}@{upn_suffix}'
if TisPKI.intermediate_ca:
crl_file = os.path.join(TisPKI.intermediate_crl_path(),'intermediate_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.intermediate_keyout_path(),'intermediate_ca.key')
dc_ca_certfile = os.path.join(TisPKI.intermediate_cert_path(),'intermediate_ca.crt')
crl_uri = config.get('openssl_config','intermediate_crl_uri')
pki_dir = TisPKI.pki_intermediate_dir()
openssl_user_file = os.path.join(TisPKI.intermediate_config_path(),'openssl_user.ini')
emailAddress = upn
commonName = username
else:
crl_file = os.path.join(TisPKI.root_crl_path(),'root_ca.crl')
dc_ca_keyfile = os.path.join(TisPKI.root_keyout_path(),'root_ca.key')
dc_ca_certfile = os.path.join(TisPKI.root_cert_path(),'root_ca.crt')
crl_uri = config.get('openssl_config','crl_uri')
pki_dir = TisPKI.pki_dir()
openssl_user_file = os.path.join(TisPKI.root_config_path(),'openssl_user.ini')
emailAddress = upn
commonName = username
template_dir = ('templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
user_tmpl = jinja_env.get_template('openssl_user_cert.tmpl')
user_tmpl_var = {
'crl_uri': crl_uri,
'pki_dir': pki_dir,
'default_cert_duration': config.get('openssl_config','default_cert_duration'),
'country': config.get('openssl_config','country'),
'state': config.get('openssl_config','state'),
'city': config.get('openssl_config','city'),
'organization_name': config.get('openssl_config','organization_name'),
'organization_ou': config.get('openssl_config','organization_ou'),
'dc_ca_keyfile': dc_ca_keyfile,
'dc_ca_certfile': dc_ca_certfile,
'default_bits_user': config.get('openssl_config','default_bits_user'),
'emailAddress' : emailAddress,
'commonName' : commonName
}
config_string = user_tmpl.render(user_tmpl_var)
with open(openssl_user_file,'wt') as file:
file.write(config_string)
if os.path.isfile(openssl_user_file):
print(f'User OpenSSL configfile is correctly generated !')
print(f'Generate private key for {upn}')
print(subprocess.run(f"openssl req -new -newkey rsa:{default_bits_user} -keyout {TisPKI.root_keyout_path()}/{username}.key -out {TisPKI.root_csr_path()}/{username}.csr -config <(cat {openssl_user_file} <(cat <<-EOF\n[ sanuser ]\notherName=msUPN;UTF8:{upn}\nemail=copy\nEOF\n)\n)",shell=True,check=True, executable='/bin/bash'))
print(f'Sign certificate')
print(subprocess.run(f'openssl ca -extensions usr_cert_scarduser -days 730 -notext -md sha512 -create_serial -in {TisPKI.root_csr_path()}/{username}.csr -out {TisPKI.root_cert_path()}/{username}.crt -config <(cat {openssl_user_file} <(cat <<-EOF\n[ sanuser ]\notherName=msUPN;UTF8:{upn}\nemail=copy\nEOF\n)\n)',shell=True,check=True, executable='/bin/bash'))
print('Remove password in rsa key')
print(subprocess.run(f'openssl rsa -in {TisPKI.root_keyout_path()}/{username}.key -out {TisPKI.root_keyout_path()}/{username}-nopasswd.key',shell=True,check=True, executable='/bin/bash'))
print('Create p12')
print(subprocess.run(f'openssl pkcs12 -export -inkey {TisPKI.root_keyout_path()}/{username}-nopasswd.key -in {TisPKI.root_cert_path()}/{username}.crt -out {TisPKI.root_p12_path()}/{username}.p12', shell=True,check=True, executable='/bin/bash'))