Пример #1
0
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
Пример #2
0
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))
Пример #3
0
 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)
Пример #4
0
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))
Пример #5
0
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))
Пример #6
0
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))
Пример #7
0
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)
Пример #8
0
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))
Пример #9
0
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
Пример #10
0
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))
Пример #11
0
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
Пример #12
0
def _reenableRpmMacros():
    mac = cleanupAbsPath('~/.rpmmacros')
    macTmp = cleanupAbsPath('~/RENAME_ME_BACK_PLEASE-lksjdflajsd.rpmmacros')
    if os.path.exists(macTmp):
        os.rename(macTmp, mac)
Пример #13
0
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
Пример #14
0
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
Пример #15
0
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))
Пример #16
0
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)
Пример #17
0
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))