Beispiel #1
0
    def Exec(self, feedback_fn):
        """Prepares an instance for an export.

    """
        if self.op.mode == constants.EXPORT_MODE_REMOTE:
            salt = utils.GenerateSecret(8)

            feedback_fn("Generating X509 certificate on %s" %
                        self.cfg.GetNodeName(self.instance.primary_node))
            result = self.rpc.call_x509_cert_create(
                self.instance.primary_node, constants.RIE_CERT_VALIDITY)
            result.Raise("Can't create X509 key and certificate on %s" %
                         self.cfg.GetNodeName(result.node))

            (name, cert_pem) = result.payload

            cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                                   cert_pem)

            return {
                "handshake":
                masterd.instance.ComputeRemoteExportHandshake(self._cds),
                "x509_key_name":
                (name, utils.Sha1Hmac(self._cds, name, salt=salt), salt),
                "x509_ca":
                utils.SignX509Certificate(cert, self._cds, salt),
            }

        return None
Beispiel #2
0
    def test(self):
        # Generate certificate valid for 5 minutes
        (_, cert_pem) = utils.GenerateSelfSignedX509Cert(None, 300, 1)

        cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                               cert_pem)

        # No signature at all
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          cert_pem, self.KEY)

        # Invalid input
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          "", self.KEY)
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          "X-Ganeti-Signature: \n", self.KEY)
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          "X-Ganeti-Sign: $1234$abcdef\n", self.KEY)
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          "X-Ganeti-Signature: $1234567890$abcdef\n", self.KEY)
        self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
                          b"X-Ganeti-Signature: $1234$abc\n\n" + cert_pem,
                          self.KEY)

        # Invalid salt
        for salt in list("-_@$,:;/\\ \t\n"):
            self.assertRaises(errors.GenericError, utils.SignX509Certificate,
                              cert_pem, self.KEY, "foo%sbar" % salt)

        for salt in [
                "HelloWorld", "salt", string.ascii_letters, string.digits,
                utils.GenerateSecret(numbytes=4),
                utils.GenerateSecret(numbytes=16),
                "{123:456}".encode("ascii").hex()
        ]:
            signed_pem = utils.SignX509Certificate(cert, self.KEY, salt)

            self._Check(cert, salt, signed_pem)

            self._Check(cert, salt,
                        "X-Another-Header: with a value\n" + signed_pem)
            self._Check(cert, salt, (10 * "Hello World!\n") + signed_pem)
            self._Check(cert, salt, (signed_pem + "\n\na few more\n"
                                     "lines----\n------ at\nthe end!"))
Beispiel #3
0
def RemoteImport(lu, feedback_fn, instance, pnode, source_x509_ca,
                 cds, compress, timeouts):
  """Imports an instance from another cluster.

  @param lu: Logical unit instance
  @param feedback_fn: Feedback function
  @type instance: L{objects.Instance}
  @param instance: Instance object
  @type pnode: L{objects.Node}
  @param pnode: Primary node of instance as an object
  @type source_x509_ca: OpenSSL.crypto.X509
  @param source_x509_ca: Import source's X509 CA
  @type cds: string
  @param cds: Cluster domain secret
  @type compress: string
  @param compress: Compression tool to use
  @type timeouts: L{ImportExportTimeouts}
  @param timeouts: Timeouts for this import

  """
  source_ca_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                                  source_x509_ca)

  magic_base = utils.GenerateSecret(6)

  # Decide whether to use IPv6
  ipv6 = netutils.IP6Address.IsValid(pnode.primary_ip)

  # Create crypto key
  result = lu.rpc.call_x509_cert_create(instance.primary_node,
                                        constants.RIE_CERT_VALIDITY)
  result.Raise("Can't create X509 key and certificate on %s" % result.node)

  (x509_key_name, x509_cert_pem) = result.payload
  try:
    # Load certificate
    x509_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                                x509_cert_pem)

    # Sign certificate
    signed_x509_cert_pem = \
      utils.SignX509Certificate(x509_cert, cds, utils.GenerateSecret(8))

    cbs = _RemoteImportCb(feedback_fn, cds, signed_x509_cert_pem,
                          len(instance.disks), pnode.primary_ip)

    ieloop = ImportExportLoop(lu)
    inst_disks = lu.cfg.GetInstanceDisks(instance.uuid)
    try:
      for idx, dev in enumerate(inst_disks):
        magic = _GetInstDiskMagic(magic_base, instance.name, idx)

        # Import daemon options
        opts = objects.ImportExportOptions(key_name=x509_key_name,
                                           ca_pem=source_ca_pem,
                                           magic=magic,
                                           compress=compress,
                                           ipv6=ipv6)

        if instance.os:
          src_io = constants.IEIO_SCRIPT
          src_ioargs = ((dev, instance), idx)
        else:
          src_io = constants.IEIO_RAW_DISK
          src_ioargs = (dev, instance)

        ieloop.Add(DiskImport(lu, instance.primary_node, opts, instance,
                              "disk%d" % idx,
                              src_io, src_ioargs,
                              timeouts, cbs, private=(idx, )))

      ieloop.Run()
    finally:
      ieloop.FinalizeAll()
  finally:
    # Remove crypto key and certificate
    result = lu.rpc.call_x509_cert_remove(instance.primary_node, x509_key_name)
    result.Raise("Can't remove X509 key and certificate on %s" % result.node)

  return cbs.disk_results