#!/usr/bin/env python3 # dlitz 2025 import sys import os import shlex import subprocess import tempfile from argparse import ArgumentParser from pathlib import Path from .cert_util import split_certs from .ssl_util import SSLUtil #from .cert_pusher import MTCertPusher from .routeros_ssh import RouterOS, SSHConnector #def generate_random_passphrase(): # return os.urandom(64).hex() def make_arg_parser(): if Path(sys.argv[0]).stem == '__main__': prog = __package__ else: prog = None parser = ArgumentParser( prog=prog, description="push TLS privkey & certificate to MikroTik RouterOS router" ) parser.add_argument( "-k", "--privkey", type=Path, required=True, help="private key file" ) parser.add_argument("--cert", type=Path, required=True, help="certificate file") parser.add_argument( "--chain", type=Path, help="separate certificate chain file (optional)" ) parser.add_argument("--ssh-config", type=Path, help="ssh config file") parser.add_argument("--ssh-host", required=True, help="target ssh host") parser.add_argument("--ssh-user", help="target ssh user") parser.add_argument("--ssh-port", type=int, help="target ssh port") return parser def parse_args(): parser = make_arg_parser() args = parser.parse_args() assert ":" not in args.ssh_host return args, parser def main(): args, parser = parse_args() # TODO: Check certificate serial number before attempting to copy cert, and at end. privkey_data = args.privkey.read_text() cert_data = args.cert.read_text() chain_data = args.chain.read_text() if args.chain is not None else None #key_passphrase = generate_random_passphrase() #chain_certs = split_certs(chain_data) ssl_util = SSLUtil() ssh_connector = SSHConnector(host=args.ssh_host, port=args.ssh_port, user=args.ssh_user, ssh_config_path=args.ssh_config) ros_remote = RouterOS(connector=ssh_connector, ssl_util=ssl_util) #ros_ssh = RouterOS_SSH(host=args.ssh_host) ros_remote.install_key_and_certificates(key=privkey_data, cert=cert_data, chain=chain_data) # pkcs12_data = sslutil.export_pkcs12( # privkey_data=privkey_data, # cert_data=cert_data, # chain_data=chain_data, # passphrase=key_passphrase, # ) # # # with tempfile.NamedTemporaryFile(dir="/dev/shm") as tf: # tf.write(pkcs12_data) # tf.flush() # # ssh_options = [ # "-oBatchMode=yes", # "-oControlMaster=no", # ] # # cmd = ["scp", *ssh_options, "-q", tf.name, f"{args.ssh_host}:/cert-pusher-data.p12"] # # print("executing:", shlex.join(cmd)) # subprocess.run(cmd, check=True) # # # ros_command = f'/certificate import name=www_ssl_cert file-name=cert-pusher-data.p12 no-key-export=yes passphrase="{key_passphrase}"' # ros_command = f'/certificate import name=www_ssl_cert file-name=cert-pusher-data.p12 no-key-export=yes passphrase="{key_passphrase}"; /file remove [/file find name=cert-pusher-data.p12]' # cmd = [ # "ssh", # *ssh_options, # args.ssh_host, # ros_command, # ] # result = subprocess.check_output(cmd, text=True) # assert " files-imported: 1" in result # # print(result) if __name__ == "__main__": main()