Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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")
Esempio n. 7
0
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)
Esempio n. 8
0
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")
Esempio n. 9
0
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))
Esempio n. 10
0
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
Esempio n. 11
0
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))
Esempio n. 12
0
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