def gen_jabberd_cert(d): """ generate the jabberd ssl cert from the server cert and key """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) server_key = os.path.join(serverKeyPairDir, d['--server-key']) server_cert = os.path.join(serverKeyPairDir, d['--server-cert']) dependencyCheck(server_key) dependencyCheck(server_cert) jabberd_ssl_cert_name = os.path.basename(d['--jabberd-ssl-cert']) jabberd_ssl_cert = os.path.join(serverKeyPairDir, jabberd_ssl_cert_name ) # Create the jabberd cert - need to concatenate the cert and the key # XXX there really should be some better error propagation here fd = None try: fd = os.open(jabberd_ssl_cert, os.O_WRONLY | os.O_CREAT) _copy_file_to_fd(cleanupAbsPath(server_cert), fd) _copy_file_to_fd(cleanupAbsPath(server_key), fd) finally: if fd: os.close(fd) return
def genPublicCaCert(password, d, verbosity=0, forceYN=0): """ public CA certificate (client-side) generation """ ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) genPublicCaCert_dependencies(password, d, forceYN) configFile = genCaConf(d, verbosity) args = ("/usr/bin/openssl req -passin pass:%s -text -config %s " "-new -x509 -days %s -%s -key %s -out %s" % ('%s', repr(cleanupAbsPath(configFile.filename)), repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(ca_key)), repr(cleanupAbsPath(ca_cert)))) if verbosity >= 0: print("\nGenerating public CA certificate: %s" % ca_cert) print("Using distinguishing variables:") for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-common-name', '--set-email'): print(' %s%s = "%s"' % (k, ' '*(18-len(k)), d[k])) if verbosity > 1: print("Commandline:", args % "PASSWORD") try: rotated = rotateFile(filepath=ca_cert, verbosity=verbosity) if verbosity>=0 and rotated: print("Rotated: %s --> %s" \ % (d['--ca-cert'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPublicCaCertException("Certificate Authority public " "SSL certificate generation failed:\n%s\n" "%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s\n' % ca_cert_name)) fo.close() # permissions: os.chmod(ca_cert, int('0644',8)) os.chmod(latest_txt, int('0644',8))
def __init__(self, filename=None): self.filename = filename if self.filename is None: self.filename = SERVER_OPENSSL_CNF_NAME if os.path.exists(os.path.join(DEFS['--dir'], 'rhn_openssl.cnf')): self.filename = os.path.join(DEFS['--dir'], "rhn_openssl.cnf") elif os.path.exists(os.path.join(DEFS['--dir'], 'openssl.cnf')): self.filename = os.path.join(DEFS['--dir'], "openssl.cnf") self.filename = cleanupAbsPath(self.filename)
def checkCaCert(d, verbosity=0): """ check CA key's password """ ca_cert = os.path.join(d['--dir'], os.path.basename(d['--ca-cert'])) args = ("/usr/bin/openssl x509 -in %s -noout" % (repr(cleanupAbsPath(cleanupAbsPath(ca_cert))))) if verbosity >= 0: print("\nChecking CA cert's validity: %s" % ca_cert) if verbosity > 1: print("Commandline:", args) ret, out_stream, err_stream = rhn_popen(args) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPrivateCaKeyException("Certificate Authority certificate " "does not exist or is broken:\n%s\n" "%s" % (out, err))
def genPrivateCaKey(password, d, verbosity=0, forceYN=0): """ private CA key generation """ gendir(d['--dir']) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) if not forceYN and os.path.exists(ca_key): sys.stderr.write("""\ ERROR: a CA private key already exists: %s If you wish to generate a new one, use the --force option. """ % ca_key) sys.exit(errnoGeneralError) args = ( "/usr/bin/openssl genpkey -pass pass:%s %s -out %s -algorithm rsa -pkeyopt rsa_keygen_bits:2048" % ('%s', CRYPTO, repr(cleanupAbsPath(ca_key)))) if verbosity >= 0: print("Generating private CA key: %s" % ca_key) if verbosity > 1: print("Commandline:", args % "PASSWORD") try: rotated = rotateFile(filepath=ca_key, verbosity=verbosity) if verbosity >= 0 and rotated: print("Rotated: %s --> %s" \ % (d['--ca-key'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenPrivateCaKeyException("Certificate Authority private SSL " "key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) # permissions: os.chmod(ca_key, int('0600', 8))
def checkCaKey(password, d, verbosity=0): """ check CA key's password """ ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) args = ("/usr/bin/openssl rsa -in %s -check -passin pass:%s" % (repr(cleanupAbsPath(cleanupAbsPath(ca_key))), "%s")) if verbosity >= 0: print("\nChecking private CA key's password: %s" % ca_key) if verbosity > 1: print("Commandline:", args % "PASSWORD") ret, out_stream, err_stream = rhn_popen(args % repr(password)) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPrivateCaKeyException("Certificate Authority private " "key's password does not match or " "key broken:\n%s\n" "%s" % (out, err))
def copyFiles(options): """ copies SSL cert and GPG key to --pub-tree if not in there already existence check should have already been done. """ pubDir = cleanupAbsPath(options.pub_tree or DEFAULT_APACHE_PUB_DIRECTORY) def copyFile(file0, file1): if not os.path.exists(os.path.dirname(file1)): sys.stderr.write("ERROR: directory does not exist:\n %s\n" % os.path.dirname(file1)) sys.exit(errnoBadPath) if not os.path.exists(file0): sys.stderr.write("ERROR: file does not exist:\n %s\n" % file0) sys.exit(errnoCANotFound) sys.stderr.write("""\ Coping file into public directory tree: %s to %s """ % (file0, file1)) shutil.copy(file0, file1) # CA SSL cert if options.ssl_cert: writeYN = 1 dest = os.path.join(pubDir, os.path.basename(options.ssl_cert)) if os.path.dirname(options.ssl_cert) != pubDir: if os.path.isfile(dest) \ and getFileChecksum('md5', options.ssl_cert) != getFileChecksum('md5', dest): rotateFile(dest, options.verbose) elif os.path.isfile(dest): writeYN = 0 if writeYN: copyFile(options.ssl_cert, dest) # corp GPG keys if not options.no_gpg and options.gpg_key: for gpg_key in options.gpg_key.split(","): writeYN = 1 dest = os.path.join(pubDir, os.path.basename(gpg_key)) if os.path.dirname(gpg_key) != pubDir: if os.path.isfile(dest) \ and getFileChecksum('md5', gpg_key) != getFileChecksum('md5', dest): rotateFile(dest, options.verbose) elif os.path.isfile(dest): writeYN = 0 if writeYN: copyFile(gpg_key, dest)
def genServerKey(d, verbosity=0): """ private server key generation """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) gendir(serverKeyPairDir) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) args = ("/usr/bin/openssl genrsa -out %s 2048" % (repr(cleanupAbsPath(server_key)))) # generate the server key if verbosity >= 0: print("\nGenerating the web server's SSL private key: %s" % server_key) if verbosity > 1: print("Commandline:", args) try: rotated = rotateFile(filepath=server_key, verbosity=verbosity) if verbosity >= 0 and rotated: print("Rotated: %s --> %s" % (d['--server-key'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenServerKeyException( "web server's SSL key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) # permissions: os.chmod(server_key, int('0600', 8))
def genServerRpm(d, verbosity=0): """ generates server's SSL key set RPM """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) server_key_name = os.path.basename(d['--server-key']) server_key = os.path.join(serverKeyPairDir, server_key_name) server_cert_name = os.path.basename(d['--server-cert']) server_cert = os.path.join(serverKeyPairDir, server_cert_name) server_cert_req_name = os.path.basename(d['--server-cert-req']) server_cert_req = os.path.join(serverKeyPairDir, server_cert_req_name) jabberd_ssl_cert_name = os.path.basename(d['--jabberd-ssl-cert']) jabberd_ssl_cert = os.path.join(serverKeyPairDir, jabberd_ssl_cert_name ) server_rpm_name = os.path.basename(d['--server-rpm']) server_rpm = os.path.join(serverKeyPairDir, server_rpm_name) postun_scriptlet = os.path.join(d['--dir'], 'postun.scriptlet') genServerRpm_dependencies(d) if verbosity>=0: sys.stderr.write("\n...working...\n") # check for old installed RPM. oldHdr = getInstalledHeader(LEGACY_SERVER_RPM_NAME1) if oldHdr and LEGACY_SERVER_RPM_NAME1 != server_rpm_name: sys.stderr.write(""" ** NOTE ** older-styled RPM installed (%s), it needs to be removed before installing the web server's RPM that is about to generated. """ % LEGACY_SERVER_RPM_NAME1) if not oldHdr: oldHdr = getInstalledHeader(LEGACY_SERVER_RPM_NAME2) if oldHdr and LEGACY_SERVER_RPM_NAME2 != server_rpm_name: sys.stderr.write(""" ** NOTE ** older-styled RPM installed (%s), it needs to be removed before installing the web server's RPM that is about to generated. """ % LEGACY_SERVER_RPM_NAME2) # check for new installed RPM. # Work out the release number. hdr = getInstalledHeader(server_rpm_name) #find RPMs in the directory as well. filenames = glob.glob("%s-*.noarch.rpm" % server_rpm) if filenames: filename = sortRPMs(filenames)[-1] h = get_package_header(filename) if hdr is None: hdr = h else: comp = hdrLabelCompare(h, hdr) if comp > 0: hdr = h epo, ver, rel = None, '1.0', '0' if hdr is not None: epo, ver, rel = hdr['epoch'], hdr['version'], hdr['release'] # bump the release - and let's not be too smart about it # assume the release is a number. if rel: rel = str(int(rel)+1) description = SERVER_RPM_SUMMARY + """ Best practices suggests that this RPM should only be installed on the web server with this hostname: %s """ % d['--set-hostname'] # Determine which jabberd user exists: jabberd_user = None possible_jabberd_users = ['jabberd', 'jabber'] for juser_attempt in possible_jabberd_users: try: pwd.getpwnam(juser_attempt) jabberd_user = juser_attempt except: # user doesn't exist, try the next pass if jabberd_user is None: print("WARNING: No jabber/jabberd user on system, skipping " + "jabberd.pem generation.") jabberd_cert_string = "" if jabberd_user is not None: jabberd_cert_string = \ "/etc/pki/spacewalk/jabberd/server.pem:0600,%s,%s=%s" % \ (jabberd_user, jabberd_user, repr(cleanupAbsPath(jabberd_ssl_cert))) ## build the server RPM args = (os.path.join(CERT_PATH, 'gen-rpm.sh') + " " "--name %s --version %s --release %s --packager %s --vendor %s " "--group 'RHN/Security' --summary %s --description %s --postun %s " "/etc/httpd/conf/ssl.key/server.key:0600=%s " "/etc/httpd/conf/ssl.crt/server.crt=%s " "%s " % (repr(server_rpm_name), ver, rel, repr(d['--rpm-packager']), repr(d['--rpm-vendor']), repr(SERVER_RPM_SUMMARY), repr(description), repr(cleanupAbsPath(postun_scriptlet)), repr(cleanupAbsPath(server_key)), repr(cleanupAbsPath(server_cert)), jabberd_cert_string )) abs_server_cert_req = cleanupAbsPath(server_cert_req) if os.path.exists(abs_server_cert_req): args += ("/etc/httpd/conf/ssl.csr/server.csr=%s" % repr(abs_server_cert_req)) else: sys.stderr.write("WARNING: Not bundling %s to server RPM " "(file not found)." % repr(server_cert_req)) serverRpmName = "%s-%s-%s" % (server_rpm, ver, rel) if verbosity >= 0: print(""" Generating web server's SSL key pair/set RPM: %s.src.rpm %s.noarch.rpm""" % (serverRpmName, serverRpmName)) if verbosity > 1: print("Commandline:", args) if verbosity >= 4: print('Current working directory:', os.getcwd()) print("Writing postun_scriptlet:", postun_scriptlet) open(postun_scriptlet, 'w').write(POST_UNINSTALL_SCRIPT) _disableRpmMacros() cwd = chdir(serverKeyPairDir) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) _reenableRpmMacros() os.unlink(postun_scriptlet) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret or not os.path.exists("%s.noarch.rpm" % serverRpmName): raise GenServerRpmException("web server's SSL key set RPM generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) os.chmod('%s.noarch.rpm' % serverRpmName, int('0600',8)) # generic the tarball necessary for Spacewalk Proxy against hosted installations tarballFilepath = genProxyServerTarball(d, version=ver, release=rel, verbosity=verbosity) # write-out latest.txt information latest_txt = os.path.join(serverKeyPairDir, 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s.noarch.rpm\n' % os.path.basename(serverRpmName))) fo.write(bstr('%s.src.rpm\n' % os.path.basename(serverRpmName))) fo.write(bstr('%s\n' % os.path.basename(tarballFilepath))) fo.close() os.chmod(latest_txt, int('0600',8)) if verbosity >= 0: print(""" Deploy the server's SSL key pair/set RPM: (NOTE: the SUSE Manager or Proxy installers may do this step for you.) The "noarch" RPM needs to be deployed to the machine working as a web server, or SUSE Manager, or SUSE Manager Proxy. Presumably %s.""" % repr(d['--set-hostname'])) return "%s.noarch.rpm" % serverRpmName
def legacyTreeFixup(d): """ move old server.* files to and "unknown" machinename directory Most of this is RHN Satellite 2.* and 3.* changes. Near the end we get to 3.6 changes. """ topdir = cleanupAbsPath(d['--dir']) oldTree = '/etc/sysconfig/rhn/ssl' if topdir != oldTree and os.path.exists(oldTree): sys.stderr.write("""\ WARNING: %s still exists even though %s is the currently configured build tree. You may wish to either (a) move %s to %s, or (b) point directly at the old tree by via the --dir option. """ % (oldTree, topdir, oldTree, topdir)) sys.stderr.write("Pausing for 5 secs") for i in range(5): sys.stderr.write("."); time.sleep(1) sys.stderr.write("\n") unknown = os.path.join(topdir, 'unknown') server_rpm_name = os.path.basename(d.get('--server-rpm', '')) serverKeyPairDir = None if '--set-hostname' in d: serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) while os.path.exists(unknown): # to avoid clashing with a possible "unknown" machinename unknown = unknown + '_' old_server_splat = os.path.join(topdir, 'server.') moveMessage = "" for ext in ('key', 'csr', 'crt'): if os.path.exists(old_server_splat+ext): gendir(unknown) files = glob.glob(old_server_splat+ext+'*') moved = [] for f in files: # move the files to the "unknown" directory new_server_splat = os.path.join(unknown, os.path.basename(f)) if not os.path.exists(new_server_splat): shutil.copy2(f, new_server_splat) os.unlink(f) moved.append(f) #if files and verbosity: if moved: s = 'server.' + ext + '*' moveMessage = moveMessage + ( ' <BUILD_DIR>/%s --> <BUILD_DIR>/%s/%s\n' % (s, os.path.basename(unknown), s)) # move legacy server SSL RPMs. But if server_rpm_name is the same name # as the target RPM name, then we move the RPMs into the appropriate # machine name directory. for name in [LEGACY_SERVER_RPM_NAME1, LEGACY_SERVER_RPM_NAME2]: old_server_rpms = glob.glob(os.path.join(topdir, name+'-*-*.*.rpm')) movedYN = 0 for old_rpm in old_server_rpms: targetDir = unknown old_hdr = get_package_header(old_rpm) if old_hdr and old_hdr['name'] == server_rpm_name and serverKeyPairDir: targetDir = serverKeyPairDir gendir(targetDir) # move the files to the targetDir directory new_rpm = os.path.join(targetDir, os.path.basename(old_rpm)) if not os.path.exists(new_rpm): shutil.copy2(old_rpm, new_rpm) os.unlink(old_rpm) movedYN = 1 if movedYN: s = name+'-*-*.{noarch,src}.rpm' moveMessage = moveMessage + """\ <BUILD_DIR>/%s --> <BUILD_DIR>/%s/%s\n""" % (s, os.path.basename(targetDir), s) # I move the first 100 .pem files I find # if there is more than that... oh well movedYN = 0 for i in range(100): serial = fixSerial(hex(i)) oldPemPath = os.path.join(topdir, serial+'.pem') newPemPath = os.path.join(unknown, serial+'.pem') if os.path.exists(oldPemPath) and not os.path.exists(newPemPath): gendir(unknown) shutil.copy2(oldPemPath, newPemPath) os.unlink(oldPemPath) movedYN = 1 if movedYN: moveMessage = moveMessage + ( ' <BUILD_DIR>/HEX*.pem --> <BUILD_DIR>/%s/HEX*.pem\n' % os.path.basename(unknown)) if moveMessage: sys.stdout.write('\nLegacy tree structured file(s) moved:\n%s' % moveMessage) # move rhn-org-httpd-ssl-MACHINENAME-VERSION.*.rpm files to the # MACHINENAME directory! (an RHN 3.6.0 change) rootFilename = pathJoin(topdir, 'rhn-org-httpd-ssl-key-pair-') filenames = glob.glob(rootFilename+'*') for filename in filenames: # note: assuming version-rel is of that form. machinename = filename[len(rootFilename):] machinename = '-'.join(machinename.split('-')[:-2]) serverKeySetDir = pathJoin(topdir, machinename) gendir(serverKeySetDir) fileto = pathJoin(serverKeySetDir, filename) if os.path.exists(fileto): rotateFile(filepath=fileto, verbosity=0) shutil.copy2(filename, fileto) os.unlink(filename) print("""\ Moved (legacy tree cleanup): %s ...moved to... %s""" % (filename, fileto))
def genCaRpm(d, verbosity=0): """ generates ssl cert RPM. """ ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) ca_cert_rpm_name = os.path.basename(d['--ca-cert-rpm']) ca_cert_rpm = os.path.join(d['--dir'], ca_cert_rpm_name) genCaRpm_dependencies(d) if verbosity>=0: sys.stderr.write("\n...working...") # Work out the release number. hdr = getInstalledHeader(ca_cert_rpm) #find RPMs in the directory filenames = glob.glob("%s-*.noarch.rpm" % ca_cert_rpm) if filenames: filename = sortRPMs(filenames)[-1] h = get_package_header(filename) if hdr is None: hdr = h else: comp = hdrLabelCompare(h, hdr) if comp > 0: hdr = h epo, ver, rel = None, '1.0', '0' if hdr is not None: epo, ver, rel = hdr['epoch'], hdr['version'], hdr['release'] # bump the release - and let's not be too smart about it # assume the release is a number. if rel: rel = str(int(rel)+1) update_trust_script = os.path.join(CERT_PATH, 'update-ca-cert-trust.sh') # build the CA certificate RPM args = (os.path.join(CERT_PATH, 'gen-rpm.sh') + " " "--name %s --version %s --release %s --packager %s --vendor %s " "--group 'RHN/Security' --summary %s --description %s " "--post %s --postun %s " "/usr/share/rhn/%s=%s" % (repr(ca_cert_rpm_name), ver, rel, repr(d['--rpm-packager']), repr(d['--rpm-vendor']), repr(CA_CERT_RPM_SUMMARY), repr(CA_CERT_RPM_SUMMARY), repr(update_trust_script), repr(update_trust_script), repr(ca_cert_name), repr(cleanupAbsPath(ca_cert)))) clientRpmName = '%s-%s-%s' % (ca_cert_rpm, ver, rel) if verbosity >= 0: print(""" Generating CA public certificate RPM: %s.src.rpm %s.noarch.rpm""" % (clientRpmName, clientRpmName)) if verbosity > 1: print("Commandline:", args) _disableRpmMacros() cwd = chdir(d['--dir']) try: ret, out_stream, err_stream = rhn_popen(args) except Exception: chdir(cwd) _reenableRpmMacros() raise chdir(cwd) _reenableRpmMacros() out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret or not os.path.exists("%s.noarch.rpm" % clientRpmName): raise GenCaCertRpmException("CA public SSL certificate RPM generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) os.chmod('%s.noarch.rpm' % clientRpmName, int('0644',8)) # write-out latest.txt information latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write(bstr('%s\n' % ca_cert_name)) fo.write(bstr('%s.noarch.rpm\n' % os.path.basename(clientRpmName))) fo.write(bstr('%s.src.rpm\n' % os.path.basename(clientRpmName))) fo.close() os.chmod(latest_txt, int('0644',8)) if verbosity >= 0: print(""" Make the public CA certificate publically available: (NOTE: the SUSE Manager Server or Proxy installers may do this step for you.) The "noarch" RPM and raw CA certificate can be made publically accessible by copying it to the /srv/www/htdocs/pub directory of your SUSE Manager Server or Proxy.""") return '%s.noarch.rpm' % clientRpmName
def _reenableRpmMacros(): mac = cleanupAbsPath('~/.rpmmacros') macTmp = cleanupAbsPath('~/RENAME_ME_BACK_PLEASE-lksjdflajsd.rpmmacros') if os.path.exists(macTmp): os.rename(macTmp, mac)
def processCommandline(): options = parseCommandline() if options.script[-3:] != '.sh': sys.stderr.write("""\ ERROR: value of --script must end in '.sh': '%s'\n""" % options.script) if not options.force: sys.stderr.write("exiting\n") sys.exit(errnoBadScriptName) options.pub_tree = cleanupAbsPath(options.pub_tree or DEFAULT_APACHE_PUB_DIRECTORY) options.overrides = os.path.basename(options.overrides) options.script = os.path.basename(options.script) if options.pub_tree.find(DEFAULT_APACHE_PUB_DIRECTORY) != 0: sys.stderr.write("WARNING: it's *highly* suggested that --pub-tree is set to:\n") sys.stderr.write(" %s\n" % DEFAULT_APACHE_PUB_DIRECTORY) sys.stderr.write(" It is currently set to:\n") sys.stderr.write(" %s\n" % options.pub_tree) if not options.force: sys.stderr.write("exiting\n") sys.exit(errnoBadPath) if options.overrides == options.script: sys.stderr.write("""\ ERROR: the value of --overrides and --script cannot be the same! '%s'\n""" % options.script) sys.exit(errnoScriptNameClash) if len(options.hostname.split('.')) < 3: msg = ("WARNING: --hostname (%s) doesn't appear to be a FQDN.\n" % options.hostname) sys.stderr.write(msg) if not options.force: sys.stderr.write("exiting\n") sys.exit(errnoNotFQDN) processCACertPath(options) if options.ssl_cert and not os.path.exists(options.ssl_cert): sys.stderr.write("ERROR: CA SSL certificate file or RPM not found\n") sys.exit(errnoCANotFound) if not options.no_gpg and options.gpg_key: for gpg_key in options.gpg_key.split(","): if not os.path.exists(gpg_key): sys.stderr.write("ERROR: corporate public GPG key file '{0}' not found\n".format(gpg_key)) sys.exit(errnoGPGNotFound) if options.http_proxy != "": options.http_proxy = parseHttpProxyString(options.http_proxy) if not options.http_proxy: options.http_proxy_username = '' if not options.http_proxy_username: options.http_proxy_password = '' # forcing numeric values for opt in ['allow_config_actions', 'allow_remote_commands', 'no_bundle', 'no_gpg', 'no_up2date', 'traditional', 'up2date', 'verbose']: # operator.truth should return (0, 1) or (False, True) depending on # the version of python; passing any of those values through int() # will return an int val = int(operator.truth(getattr(options, opt))) if opt == 'traditional': setattr(options, 'salt', int(not bool(val))) else: setattr(options, opt, val) return options
def genServerCert(password, d, verbosity=0): """ server cert generation and signing """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) genServerCert_dependencies(password, d, verbosity) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert = os.path.join(d['--dir'], os.path.basename(d['--ca-cert'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_cert = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert'])) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) index_txt = os.path.join(d['--dir'], 'index.txt') serial = os.path.join(d['--dir'], 'serial') try: os.unlink(index_txt) except: pass # figure out the serial file and truncate the index.txt file. ser = figureSerial(ca_cert, serial, index_txt) # need to insure the directory declared in the ca_openssl.cnf # file is current: configFile = ConfigFile(ca_openssl_cnf) configFile.updateDir() args = ("/usr/bin/openssl ca -extensions req_server_x509_extensions -passin pass:%s -outdir ./ -config %s " "-in %s -batch -cert %s -keyfile %s -startdate %s -days %s " "-md %s -out %s" % ('%s', repr(cleanupAbsPath(ca_openssl_cnf)), repr(cleanupAbsPath(server_cert_req)), repr(cleanupAbsPath(ca_cert)), repr(cleanupAbsPath(ca_key)), d['--startdate'], repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(server_cert)))) if verbosity >= 0: print("\nGenerating/signing web server's SSL certificate: %s" % d['--server-cert']) if verbosity > 1: print("Commandline:", args % 'PASSWORD') try: rotated = rotateFile(filepath=server_cert, verbosity=verbosity) if verbosity>=0 and rotated: print("Rotated: %s --> %s" % (d['--server-cert'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = sstr(out_stream.read()); out_stream.close() err = sstr(err_stream.read()); err_stream.close() if ret: # signature for a mistyped CA password if err.find("unable to load CA private key") != -1 \ and err.find("error:0906A065:PEM routines:PEM_do_header:bad decrypt:pem_lib.c") != -1 \ and err.find("error:06065064:digital envelope routines:EVP_DecryptFinal:bad decrypt:evp_enc.c") != -1: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\nDid you mistype your CA password?") else: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) # permissions: os.chmod(server_cert, int('0644',8)) # cleanup duplicate XX.pem file: pemFilename = os.path.basename(ser.upper()+'.pem') if pemFilename != server_cert and os.path.exists(pemFilename): os.unlink(pemFilename) # cleanup the old index.txt file try: os.unlink(index_txt + '.old') except: pass # cleanup the old serial file try: os.unlink(serial + '.old') except: pass
def genServerCertReq(d, verbosity=0): """ private server cert request generation """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_openssl_cnf = os.path.join(serverKeyPairDir, SERVER_OPENSSL_CNF_NAME) genServerCertReq_dependencies(d) # XXX: hmm.. should private_key, etc. be set for this before the write? # either that you pull the key/certs from the files all together? configFile = ConfigFile(server_openssl_cnf) if '--set-common-name' in d: del d['--set-common-name'] configFile.save(d, caYN=0, verbosity=verbosity) ## generate the server cert request args = ("/usr/bin/openssl req -%s -text -config %s -new -key %s -out %s " % (MD, repr(cleanupAbsPath(configFile.filename)), repr(cleanupAbsPath(server_key)), repr(cleanupAbsPath(server_cert_req)))) if verbosity >= 0: print("\nGenerating web server's SSL certificate request: %s" % server_cert_req) print("Using distinguished names:") for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-hostname', '--set-email'): print(' %s%s = "%s"' % (k, ' '*(18-len(k)), d[k])) if verbosity > 1: print("Commandline:", args) try: rotated = rotateFile(filepath=server_cert_req, verbosity=verbosity) if verbosity>=0 and rotated: print("Rotated: %s --> %s" % (d['--server-cert-req'], os.path.basename(rotated))) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenServerCertReqException( "web server's SSL certificate request generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print("STDOUT:", out) if err: print("STDERR:", err) # permissions: os.chmod(server_cert_req, int('0600',8))
def generateBootstrapScript(options): "write, copy and place files into <DEFAULT_APACHE_PUB_DIRECTORY>/bootstrap/" orgCACert = os.path.basename(options.ssl_cert or '') # write to <DEFAULT_APACHE_PUB_DIRECTORY>/bootstrap/<options.overrides> writeClientConfigOverrides(options) isRpmYN = processCACertPath(options) pubname = os.path.basename(options.pub_tree) newScript = [] # generate script # In processCommandline() we have turned all boolean values to 0 or 1 # this means that we can negate those booleans with 1 - their current # value (instead of doing not value which can yield True/False, which # would print as such) newScript.append( getHeader( MY_PRODUCT_NAME, options, orgCACert, isRpmYN, pubname, DEFAULT_APACHE_PUB_DIRECTORY ) ) writeYN = 1 # concat all those script-bits newScript.append(getConfigFilesSh()) # don't call this twice # getUp2dateScriptsSh() newScript.append(getGPGKeyImportSh()) newScript.append(getCorpCACertSh()) # SLES: install packages required for registration on systems that do not have them installed newScript.append(getRegistrationStackSh(options.salt)) if not options.salt: newScript.append(getUp2dateScriptsSh()) if (options.salt): newScript.append(removeTLSCertificate()) newScript.append(getRegistrationSaltSh(MY_PRODUCT_NAME)) else: newScript.append(getRegistrationSh(MY_PRODUCT_NAME)) #5/16/05 wregglej 159437 - moving stuff that messes with the allowed-action dir to after registration if not options.salt: newScript.append(getAllowConfigManagement()) newScript.append(getAllowRemoteCommands()) #5/16/05 wregglej 159437 - moved the stuff that up2dates the entire box to after allowed-actions permissions are set. newScript.append(getUp2dateTheBoxSh(MY_PRODUCT_NAME, options.salt)) _bootstrapDir = cleanupAbsPath(os.path.join(options.pub_tree, 'bootstrap')) _script = cleanupAbsPath(os.path.join(_bootstrapDir, options.script)) newScript = ''.join(newScript) if os.path.exists(_script): oldScript = open(_script, 'r').read() if oldScript == newScript: writeYN = 0 elif os.path.exists(_script): backup = rotateFile(_script, depth=5, verbosity=options.verbose) if backup and options.verbose>=0: print("* rotating %s --> %s" % (_script, backup)) del oldScript if writeYN: fout = open(_script, 'w') fout.write(newScript) fout.close() print("""\ * bootstrap script (written): '%s'\n""" % _script) else: print("""\ * boostrap script (old and new scripts identical; not written): '%s'\n""" % _script)
def writeClientConfigOverrides(options): """ write our "overrides" configuration file This generated file is a configuration mapping file that is used to map settings in up2date and rhn_register when run through a seperate script. """ up2dateConfMap = { # some are directly mapped, others are handled more delicately 'http_proxy': 'httpProxy', 'http_proxy_username': '******', 'http_proxy_password': '******', 'hostname': 'serverURL', 'ssl_cert': 'sslCACert', 'no_gpg': 'useGPG', } _bootstrapDir = cleanupAbsPath(os.path.join(options.pub_tree, 'bootstrap')) if not os.path.exists(_bootstrapDir): print("* creating '%s'" % _bootstrapDir) os.makedirs(_bootstrapDir) # permissions should be fine d = {} if options.hostname: d['serverURL'] = 'https://' + options.hostname + '/XMLRPC' # if proxy, enable it # if "", disable it if options.http_proxy: d['enableProxy'] = '1' d[up2dateConfMap['http_proxy']] = options.http_proxy else: d['enableProxy'] = '0' d[up2dateConfMap['http_proxy']] = "" # if proxy username, enable auth proxy # if "", disable it if options.http_proxy_username: d['enableProxyAuth'] = '1' d[up2dateConfMap['http_proxy_username']] = options.http_proxy_username d[up2dateConfMap['http_proxy_password']] = options.http_proxy_password else: d['enableProxyAuth'] = '0' d[up2dateConfMap['http_proxy_username']] = "" d[up2dateConfMap['http_proxy_password']] = "" # CA SSL certificate is a bit complicated. options.ssl_cert may be a file # or it may be an RPM or it may be "", which means "try to figure it out # by searching through the --pub-tree on your own. _isRpmYN = processCACertPath(options) if not options.ssl_cert: sys.stderr.write("WARNING: no SSL CA certificate or RPM found in %s\n" % options.pub_tree) _certname = os.path.basename(options.ssl_cert) or CA_CRT_NAME _certdir = os.path.dirname(DEFAULT_CA_CERT_PATH) if _isRpmYN: hdr = rhn_rpm.get_package_header(options.ssl_cert) # Grab the first file out of the rpm d[up2dateConfMap['ssl_cert']] = hdr[rhn_rpm.rpm.RPMTAG_FILENAMES][0] # UGLY! else: d[up2dateConfMap['ssl_cert']] = os.path.join(_certdir, _certname) d[up2dateConfMap['no_gpg']] = int(operator.truth(not options.no_gpg)) writeYN = 1 _overrides = cleanupAbsPath(os.path.join(_bootstrapDir, options.overrides)) if os.path.exists(_overrides): if readConfigFile(_overrides) != d: # only back it up if different backup = rotateFile(_overrides, depth=5, verbosity=options.verbose) if backup and options.verbose>=0: print("""\ * WARNING: if there were hand edits to the rotated (backed up) file, some settings may need to be migrated.""") else: # exactly the same... no need to write writeYN = 0 print("""\ * client configuration overrides (old and new are identical; not written): '%s'\n""" % _overrides) if writeYN: fout = open(_overrides, 'w') # header fout.write("""\ # RHN Client (rhn_register/up2date) config-overrides file v4.0 # # To be used only in conjuction with client_config_update.py # # This file was autogenerated. # # The simple rules: # - a setting explicitely overwrites the setting in # /etc/syconfig/rhn/{rhn_register,up2date} on the client system. # - if a setting is removed, the client's state for that setting remains # unchanged. """) keys = list(d.keys()) keys.sort() for key in keys: if d[key] is not None: fout.write("%s=%s\n" % (key, d[key])) fout.close() print("""\ * bootstrap overrides (written): '%s'\n""" % _overrides) if options.verbose>=0: print("Values written:") for k, v in list(d.items()): print(k + ' '*(25-len(k)) + repr(v))