1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#!/usr/bin/env python
import numbers
import os
import posix
import socket
import shutil
from subprocess import Popen, PIPE
import sys
IRODS_SSL_DIR = "/etc/irods/ssl"
SERVER_CERT_HOSTNAME = None
ext = ""
keep_old = False
def create_server_cert(
process_output=sys.stdout, irods_key_path="irods.key", hostname=SERVER_CERT_HOSTNAME
):
p = Popen(
"openssl req -new -x509 -key '{irods_key_path}' -out irods.crt{ext} -days 365 <<EOF{_sep_}"
"US{_sep_}North Carolina{_sep_}Chapel Hill{_sep_}UNC{_sep_}RENCI{_sep_}"
"{host}{_sep_}anon@mail.com{_sep_}EOF\n"
"".format(
ext=ext,
host=(hostname if hostname else socket.gethostname()),
_sep_="\n",
**locals()
),
shell=True,
stdout=process_output,
stderr=process_output,
)
p.wait()
return p.returncode
def create_ssl_dir(
irods_key_path="irods.key", ssl_dir="", use_strong_primes_for_dh_generation=True
):
ssl_dir = ssl_dir or IRODS_SSL_DIR
save_cwd = os.getcwd()
silent_run = {"shell": True, "stderr": PIPE, "stdout": PIPE}
try:
if not (os.path.exists(ssl_dir)):
os.mkdir(ssl_dir)
os.chdir(ssl_dir)
if not keep_old:
Popen(
"openssl genrsa -out '{irods_key_path}' 2048 && chmod 600 '{irods_key_path}'".format(
**locals()
),
**silent_run
).communicate()
with open("/dev/null", "wb") as dev_null:
if 0 == create_server_cert(
process_output=dev_null, irods_key_path=irods_key_path
):
if not keep_old:
# https://www.openssl.org/docs/man1.0.2/man1/dhparam.html#:~:text=DH%20parameter%20generation%20with%20the,that%20may%20be%20possible%20otherwise.
if use_strong_primes_for_dh_generation:
dhparam_generation_command = (
"openssl dhparam -2 -out dhparams.pem"
)
else:
dhparam_generation_command = (
"openssl dhparam -dsaparam -out dhparams.pem 4096"
)
print("cmd=", dhparam_generation_command)
Popen(dhparam_generation_command, **silent_run).communicate()
return os.listdir(".")
finally:
os.chdir(save_cwd)
def test(options, args=()):
if args:
print("warning: non-option args are ignored", file=sys.stderr)
force = "-f" in options
affirm = "n" if (os.path.exists(IRODS_SSL_DIR) and not force) else "y"
if affirm == "n" and posix.isatty(sys.stdin.fileno()):
try:
input_ = raw_input
except NameError:
input_ = input
affirm = input_(
"This will overwrite directory '{}'. Proceed(Y/N)? ".format(IRODS_SSL_DIR)
)
if affirm[:1].lower() == "y":
if not keep_old:
shutil.rmtree(IRODS_SSL_DIR, ignore_errors=True)
dh_strong_primes = "-q" not in options
wait_warning = " This may take a while." if dh_strong_primes else ""
print(
"Generating new '{}'.{}".format(IRODS_SSL_DIR, wait_warning),
file=sys.stderr,
)
ssl_dir_files = create_ssl_dir(
use_strong_primes_for_dh_generation=dh_strong_primes
)
print("ssl_dir_files=", ssl_dir_files, file=sys.stderr)
def usage(exit_code=None):
print(
"""Usage: {sys.argv[0]} [-f] [-h <hostname>] [-k] [-q] [-x <extension>]
-f Force replacement of the existing SSL directory (/etc/irods/ssl) with a new one, containing newly generated files.
-h In the generated certificate, use the given hostname rather than the value returned from socket.gethostname()
-k (Keep old secrets files.) Do not generate new key file or dhparams.pem file.
-q For testing; do a quick generation of a dhparams.pem file rather than waiting on system entropy to make it more secure.
-x Optional extra extension for appending to end of the filename for the generated certificate.
--help Print this help.
Any invalid option prints this help.
""".format(
**globals()
),
file=sys.stderr,
)
if isinstance(exit_code, numbers.Integral):
exit(exit_code)
if __name__ == "__main__":
import getopt
try:
opt, arg_list = getopt.getopt(sys.argv[1:], "x:fh:kq", ["help"])
except getopt.GetoptError:
usage(exit_code=1)
opt_lookup = dict(opt)
if "--help" in opt_lookup:
usage(exit_code=0)
ext = opt_lookup.get("-x", "")
if ext:
ext = "." + ext.lstrip(".")
keep_old = opt_lookup.get("-k") is not None
SERVER_CERT_HOSTNAME = opt_lookup.get("-h")
test(opt_lookup, arg_list)
|