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
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!"))
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