def SetEtcHostsEntry(file_name, ip, hostname, aliases): """Sets the name of an IP address and hostname in /etc/hosts. @type file_name: str @param file_name: path to the file to modify (usually C{/etc/hosts}) @type ip: str @param ip: the IP address @type hostname: str @param hostname: the hostname to be added @type aliases: list @param aliases: the list of aliases to add for the hostname """ # Ensure aliases are unique names = algo.UniqueSequence([hostname] + aliases) out = StringIO() def _write_entry(written): if not written: out.write("%s\t%s\n" % (ip, " ".join(names))) return True written = False for line in io.ReadFile(file_name).splitlines(True): fields = line.split() if fields and not fields[0].startswith("#") and ip == fields[0]: written = _write_entry(written) else: out.write(line) _write_entry(written) io.WriteFile(file_name, data=out.getvalue(), uid=0, gid=0, mode=0644, keep_perms=io.KP_IF_EXISTS)
def RemoveEtcHostsEntry(file_name, hostname): """Removes a hostname from /etc/hosts. IP addresses without names are removed from the file. @type file_name: str @param file_name: path to the file to modify (usually C{/etc/hosts}) @type hostname: str @param hostname: the hostname to be removed """ out = StringIO() for line in io.ReadFile(file_name).splitlines(True): fields = line.split() if len(fields) > 1 and not fields[0].startswith("#"): names = fields[1:] if hostname in names: while hostname in names: names.remove(hostname) if names: out.write("%s %s\n" % (fields[0], " ".join(names))) continue out.write(line) io.WriteFile(file_name, data=out.getvalue(), uid=0, gid=0, mode=0644, keep_perms=io.KP_IF_EXISTS)
def IsCertificateSelfSigned(cert_filename): """Checks whether the certificate issuer is the same as the owner. Note that this does not actually verify the signature, it simply compares the certificates common name and the issuer's common name. This is sufficient, because now that Ganeti started creating non-self-signed client-certificates, it uses their hostnames as common names and thus they are distinguishable by common name from the server certificates. @type cert_filename: string @param cert_filename: filename of the certificate to examine """ try: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, io.ReadFile(cert_filename)) except Exception as err: # pylint: disable=W0703 return (constants.CV_ERROR, "Failed to load X509 certificate %s: %s" % (cert_filename, err)) if cert.get_subject().CN == cert.get_issuer().CN: msg = "The certificate '%s' is self-signed. Please run 'gnt-cluster" \ " renew-crypto --new-node-certificates' to get a properly signed" \ " certificate." % cert_filename return (constants.CV_WARNING, msg) return (None, None)
def VerifyCertificate(filename): """Verifies a SSL certificate. @type filename: string @param filename: Path to PEM file """ try: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, io.ReadFile(filename)) except Exception as err: # pylint: disable=W0703 return (constants.CV_ERROR, "Failed to load X509 certificate %s: %s" % (filename, err)) (errcode, msg) = \ x509.VerifyX509Certificate(cert, constants.SSL_CERT_EXPIRATION_WARN, constants.SSL_CERT_EXPIRATION_ERROR) if msg: fnamemsg = "While verifying %s: %s" % (filename, msg) else: fnamemsg = None if errcode is None: return (None, fnamemsg) elif errcode == x509.CERT_WARNING: return (constants.CV_WARNING, fnamemsg) elif errcode == x509.CERT_ERROR: return (constants.CV_ERROR, fnamemsg) raise errors.ProgrammerError("Unhandled certificate error code %r" % errcode)
def IsProcessHandlingSignal(pid, signum, status_path=None): """Checks whether a process is handling a signal. @type pid: int @param pid: Process ID @type signum: int @param signum: Signal number @rtype: bool """ if status_path is None: status_path = _GetProcStatusPath(pid) try: proc_status = utils_io.ReadFile(status_path) except EnvironmentError as err: # In at least one case, reading /proc/$pid/status failed with ESRCH. if err.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL, errno.ESRCH): return False raise sigcgt = _GetProcStatusField(proc_status, "SigCgt") if sigcgt is None: raise RuntimeError("%s is missing 'SigCgt' field" % status_path) # Now check whether signal is handled return signum in _ParseSigsetT(sigcgt)
def GetCertificateDigest(cert_filename=pathutils.NODED_CLIENT_CERT_FILE): """Reads the SSL certificate and returns the sha1 digest. """ cert_plain = io.ReadFile(cert_filename) cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_plain) return cert.digest("sha1")
def GenerateSignedSslCert(filename_cert, serial_no, filename_signing_cert, common_name=constants.X509_CERT_CN, validity=constants.X509_CERT_DEFAULT_VALIDITY, uid=-1, gid=-1): signing_cert_pem = utils_io.ReadFile(filename_signing_cert) (key_pem, cert_pem) = GenerateSignedX509Cert( common_name, validity * 24 * 60 * 60, serial_no, signing_cert_pem) utils_io.WriteFile(filename_cert, mode=0o440, data=key_pem + cert_pem, uid=uid, gid=gid, backup=True) return (key_pem, cert_pem)
def CheckNodeCertificate(cert, _noded_cert_file=pathutils.NODED_CERT_FILE): """Checks the local node daemon certificate against given certificate. Both certificates must be signed with the same key (as stored in the local L{pathutils.NODED_CERT_FILE} file). No error is raised if no local certificate can be found. @type cert: OpenSSL.crypto.X509 @param cert: X509 certificate object @raise errors.X509CertError: When an error related to X509 occurred @raise errors.GenericError: When the verification failed """ try: noded_pem = utils_io.ReadFile(_noded_cert_file) except EnvironmentError as err: if err.errno != errno.ENOENT: raise logging.debug("Node certificate file '%s' was not found", _noded_cert_file) return try: noded_cert = \ OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, noded_pem) except Exception as err: raise errors.X509CertError(_noded_cert_file, "Unable to load certificate: %s" % err) try: noded_key = \ OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, noded_pem) except Exception as err: raise errors.X509CertError(_noded_cert_file, "Unable to load private key: %s" % err) # Check consistency of server.pem file try: X509CertKeyCheck(noded_cert, noded_key) except OpenSSL.SSL.Error: # This should never happen as it would mean the certificate in server.pem # is out of sync with the private key stored in the same file raise errors.X509CertError( _noded_cert_file, "Certificate does not match with private key") # Check with supplied certificate with local key try: X509CertKeyCheck(cert, noded_key) except OpenSSL.SSL.Error: raise errors.GenericError("Given cluster certificate does not match" " local key")
def VerifyCertificate(filename): """Verifies a SSL certificate. @type filename: string @param filename: Path to PEM file """ try: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, io.ReadFile(filename)) except Exception, err: # pylint: disable=W0703 return (constants.CV_ERROR, "Failed to load X509 certificate %s: %s" % (filename, err))
def IsProcessHandlingSignal(pid, signum, status_path=None): """Checks whether a process is handling a signal. @type pid: int @param pid: Process ID @type signum: int @param signum: Signal number @rtype: bool """ if status_path is None: status_path = _GetProcStatusPath(pid) try: proc_status = utils_io.ReadFile(status_path) except EnvironmentError, err: # In at least one case, reading /proc/$pid/status failed with ESRCH. if err.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL, errno.ESRCH): return False raise
def IsCertificateSelfSigned(cert_filename): """Checks whether the certificate issuer is the same as the owner. Note that this does not actually verify the signature, it simply compares the certificates common name and the issuer's common name. This is sufficient, because now that Ganeti started creating non-self-signed client-certificates, it uses their hostnames as common names and thus they are distinguishable by common name from the server certificates. @type cert_filename: string @param cert_filename: filename of the certificate to examine """ try: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, io.ReadFile(cert_filename)) except Exception, err: # pylint: disable=W0703 return (constants.CV_ERROR, "Failed to load X509 certificate %s: %s" % (cert_filename, err))
def CheckNodeCertificate(cert, _noded_cert_file=pathutils.NODED_CERT_FILE): """Checks the local node daemon certificate against given certificate. Both certificates must be signed with the same key (as stored in the local L{pathutils.NODED_CERT_FILE} file). No error is raised if no local certificate can be found. @type cert: OpenSSL.crypto.X509 @param cert: X509 certificate object @raise errors.X509CertError: When an error related to X509 occurred @raise errors.GenericError: When the verification failed """ try: noded_pem = utils_io.ReadFile(_noded_cert_file) except EnvironmentError, err: if err.errno != errno.ENOENT: raise logging.debug("Node certificate file '%s' was not found", _noded_cert_file) return