From 240ed65f3077ce357f9572392f21c8a5dda19a44 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:03:06 +0100 Subject: [PATCH 1/6] cigetcert: use winkerberos on windows --- cigetcert | 6 +++++- setup.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cigetcert b/cigetcert index 3aec6a3..fe955a4 100755 --- a/cigetcert +++ b/cigetcert @@ -57,7 +57,6 @@ except ImportError: # python < 3 from urllib import urlencode urllib_parse.urlencode = urlencode -import kerberos from lxml import etree from M2Crypto import SSL, X509, EVP, RSA, ASN1, m2 from OpenSSL import crypto @@ -65,6 +64,11 @@ from OpenSSL import crypto import shlex from optparse import OptionParser +if os.name == "nt": + import winkerberos as kerberos +else: + import kerberos + # get the default certificates paths for this platform _default_cafile = '/etc/ssl/certs/ca-certificates.crt' # debian _default_capath = "/etc/grid-security/certificates" diff --git a/setup.py b/setup.py index 8936db0..d247e55 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,7 @@ def find_version(path, varname="__version__"): install_requires=[ "lxml", "M2Crypto", - "pykerberos", + "winkerberos" if os.name == "nt" else "pykerberos", "pyOpenSSL", ], ) From f10dd8c5c057bfdcb43b87da155d96c4bf781616 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:07:07 +0100 Subject: [PATCH 2/6] cigetcert: improved handling of default cafile/capath mainly to support not using posix paths on windows --- cigetcert | 56 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/cigetcert b/cigetcert index fe955a4..4cc704a 100755 --- a/cigetcert +++ b/cigetcert @@ -44,6 +44,7 @@ import calendar import ssl import struct import tempfile +import platform try: from http import (client as http_client, cookiejar as http_cookiejar) @@ -69,28 +70,10 @@ if os.name == "nt": else: import kerberos -# get the default certificates paths for this platform -_default_cafile = '/etc/ssl/certs/ca-certificates.crt' # debian -_default_capath = "/etc/grid-security/certificates" -try: - _paths = ssl.get_default_verify_paths() -except AttributeError: # python < 2.7 - pass -else: - # always prefer python's default cafile - if _paths.cafile: - _default_cafile = _paths.cafile - # prefer grid-security default capath - if _paths.capath and not os.path.isdir(_default_capath): - _default_capath = _paths.capath -if not os.path.isfile(_default_cafile or ''): # use ca-certificates file: - _default_cafile = "/etc/pki/tls/cert.pem" defaults = { "spurl": "https://ecp.cilogon.org/secure/getcert", "idplisturl": "https://cilogon.org/include/ecpidps.txt", - "cafile": _default_cafile, - "capath": _default_capath, } # these are global @@ -98,6 +81,41 @@ options = None showprogress = False +def get_ca_defaults(): + # on Windows and macOS, always trust the built-in defaults + if platform.system() in {"Windows", "Darwin"}: + paths = ssl.get_default_verify_paths() + return { + "cafile": paths.cafile, + "capath": paths.capath, + } + + # on Linux we can be a bit more discerning + cafile = '/etc/ssl/certs/ca-certificates.crt' # debian + capath = "/etc/grid-security/certificates" + try: + paths = ssl.get_default_verify_paths() + except AttributeError: # python < 2.7 + pass + else: + # always prefer python's default cafile + if paths.cafile: + cafile = paths.cafile + # prefer grid-security default capath + if paths.capath and not os.path.isdir(capath): + capath = paths.capath + if not os.path.isfile(cafile or ''): # use ca-certificates file: + cafile = "/etc/pki/tls/cert.pem" + + return { + "cafile": cafile, + "capath": capath, + } + + +defaults.update(get_ca_defaults()) + + def usage(parser, msg): print(prog + ": " + msg + '\n', file=sys.stderr) parser.print_help(sys.stderr) @@ -496,7 +514,7 @@ def main(): metavar="path", help="Certifying Authority certificates directory " + '[default: $X509_CERT_DIR or ' + - defaults['capath'] + ']') + str(defaults['capath']) + ']') parser.add_option("-k", "--kerberos", action="store_const", const=1, default=0, help="prefer kerberos authentication if available") From a44b3fefcfa424e900e61552a7961dd1a9461ec2 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:08:12 +0100 Subject: [PATCH 3/6] cigetcert: new default output file for windows see fermitools/cigetcert#65 --- cigetcert | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cigetcert b/cigetcert index 4cc704a..a184b0d 100755 --- a/cigetcert +++ b/cigetcert @@ -81,6 +81,19 @@ options = None showprogress = False +def get_default_output_filename(): + if os.name == "nt": + tmpdir = os.path.expandvars(r'%SYSTEMROOT%\Temp') + tmpname = "x509up_{}".format(USERNAME) + else: + tmpdir = "/tmp" + tmpname = "x509up_u{}".format(os.getuid()) + return os.path.join(tmpdir, tmpname) + + +defaults["out"] = get_default_output_filename() + + def get_ca_defaults(): # on Windows and macOS, always trust the built-in defaults if platform.system() in {"Windows", "Darwin"}: @@ -533,7 +546,7 @@ def main(): parser.add_option("-o", "--out", metavar="path", help="file path to save certificate and key chain " + - "[default: $X509_USER_PROXY or /tmp/x509up_u%uid]") + "[default: $X509_USER_PROXY or {}]".format(defaults["out"])) parser.add_option("", "--reuseonly", action="store_const", const=1, default=0, help="only verify existing proxy can be reused " + @@ -663,9 +676,7 @@ def main(): # calculate defaults for options that are too complex for "default" keyword if options.out is None: - options.out = os.getenv("X509_USER_PROXY") - if options.out is None: - options.out = "/tmp/x509up_u%uid" + options.out = os.getenv("X509_USER_PROXY", defaults["out"]) if options.hours > maxproxyhours: if options.proxyhours is None: options.proxyhours = defproxyhours @@ -731,7 +742,9 @@ def main(): username = options.username.replace( "%currentuser", pwd.getpwuid(os.geteuid()).pw_name) myproxyusername = options.myproxyusername.replace("%username", username) - outfile = options.out.replace("%uid", str(os.geteuid())) + outfile = options.out + if "%uid" in outfile: # this doesn't exist on windows + outfile = outfile.replace("%uid", str(os.geteuid())) if os.path.exists(outfile): if options.reuseonly == 0: if not os.access(outfile, os.W_OK): From c7cdf57e3b3073838c1fccbe0ef09b59acf9a289 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:09:14 +0100 Subject: [PATCH 4/6] cigetcert: use os.getlogin for username this exists on windows as well (python>=3.0) --- cigetcert | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cigetcert b/cigetcert index a184b0d..4d01058 100755 --- a/cigetcert +++ b/cigetcert @@ -32,7 +32,6 @@ version = "1.19" import sys import os import re -import pwd import socket import getpass import base64 @@ -70,6 +69,7 @@ if os.name == "nt": else: import kerberos +USERNAME = os.getlogin() defaults = { "spurl": "https://ecp.cilogon.org/secure/getcert", @@ -739,8 +739,7 @@ def main(): print() # Check to see if an adequate proxy or cert already exists - username = options.username.replace( - "%currentuser", pwd.getpwuid(os.geteuid()).pw_name) + username = options.username.replace("%currentuser", USERNAME) myproxyusername = options.myproxyusername.replace("%username", username) outfile = options.out if "%uid" in outfile: # this doesn't exist on windows From 71479cb5096385b57ce53b32ae946b97fcbfaff5 Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:10:06 +0100 Subject: [PATCH 5/6] cigetcert: use bytes for password --- cigetcert | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cigetcert b/cigetcert index 4d01058..f036d07 100755 --- a/cigetcert +++ b/cigetcert @@ -1213,8 +1213,11 @@ def main(): # The ascii letters are for strength, the digits and special characters # are just in case future rules enforce such things. # Could instead use a CSR but that limits certificates to 277 hours. - p12password = random_string(16, string.ascii_letters) + \ - random_string(2, string.digits) + random_string(2, '!@#$%^&*()') + p12password = ( + random_string(16, string.ascii_letters) + + random_string(2, string.digits) + + random_string(2, '!@#$%^&*()') + ).encode("utf-8") certformvars = [ ('submit', 'pkcs12'), From f0c32da09c8de08109df3bc58d7592df3c44e32e Mon Sep 17 00:00:00 2001 From: Duncan Macleod Date: Fri, 26 Jul 2019 08:10:25 +0100 Subject: [PATCH 6/6] cigetcert: path fix for windows --- cigetcert | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cigetcert b/cigetcert index f036d07..8f3ad93 100755 --- a/cigetcert +++ b/cigetcert @@ -1305,7 +1305,11 @@ def main(): pass try: fd, path = tempfile.mkstemp( - prefix=os.path.dirname(outfile)+'/.cigetcert') + prefix=os.path.join( + os.path.dirname(outfile), + '.cigetcert', + ), + ) handle = os.fdopen(fd, 'wb') except Exception as e: efatal("failure creating file", e)