Beispiel #1
0
    def _decrypt_image(self, context, encrypted_filename, encrypted_key,
                       encrypted_iv, decrypted_filename):
        elevated = context.elevated()
        try:
            key = self.cert_rpcapi.decrypt_text(elevated,
                    project_id=context.project_id,
                    text=base64.b64encode(encrypted_key))
        except Exception as exc:
            msg = _('Failed to decrypt private key: %s') % exc
            raise exception.NovaException(msg)
        try:
            iv = self.cert_rpcapi.decrypt_text(elevated,
                    project_id=context.project_id,
                    text=base64.b64encode(encrypted_iv))
        except Exception as exc:
            raise exception.NovaException(_('Failed to decrypt initialization '
                                    'vector: %s') % exc)

        try:
            utils.execute('openssl', 'enc',
                          '-d', '-aes-128-cbc',
                          '-in', '%s' % (encrypted_filename,),
                          '-K', '%s' % (key,),
                          '-iv', '%s' % (iv,),
                          '-out', '%s' % (decrypted_filename,))
        except processutils.ProcessExecutionError as exc:
            raise exception.NovaException(_('Failed to decrypt image file '
                                    '%(image_file)s: %(err)s') %
                                    {'image_file': encrypted_filename,
                                     'err': exc.stdout})
Beispiel #2
0
    def test_create_configdrive_vfat(self):
        CONF.set_override('config_drive_format', 'vfat')
        imagefile = None
        try:
            self.mox.StubOutWithMock(utils, 'mkfs')
            self.mox.StubOutWithMock(utils, 'execute')
            self.mox.StubOutWithMock(utils, 'trycmd')

            utils.mkfs('vfat', mox.IgnoreArg(),
                       label='config-2').AndReturn(None)
            utils.trycmd('mount', '-o', mox.IgnoreArg(), mox.IgnoreArg(),
                         mox.IgnoreArg(),
                         run_as_root=True).AndReturn((None, None))
            utils.execute('umount', mox.IgnoreArg(),
                          run_as_root=True).AndReturn(None)

            self.mox.ReplayAll()

            with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c:
                (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_')
                os.close(fd)
                c.make_drive(imagefile)

            # NOTE(mikal): we can't check for a VFAT output here because the
            # filesystem creation stuff has been mocked out because it
            # requires root permissions

        finally:
            if imagefile:
                fileutils.delete_if_exists(imagefile)
Beispiel #3
0
    def attach_volume(self, context, **kwargs):
        """Shadows the device and passes an unencrypted version to the
        instance.

        Transparent disk encryption is achieved by mounting the volume via
        dm-crypt and passing the resulting device to the instance. The
        instance is unaware of the underlying encryption due to modifying the
        original symbolic link to refer to the device mounted by dm-crypt.
        """

        key = self._get_key(context).get_encoded()
        passphrase = self._get_passphrase(key)

        try:
            self._open_volume(passphrase, **kwargs)
        except processutils.ProcessExecutionError as e:
            if e.exit_code == 1 and not is_luks(self.dev_path):
                # the device has never been formatted; format it and try again
                LOG.info(
                    _LI("%s is not a valid LUKS device;"
                        " formatting device for first use"), self.dev_path)
                self._format_volume(passphrase, **kwargs)
                self._open_volume(passphrase, **kwargs)
            else:
                raise

        # modify the original symbolic link to refer to the decrypted device
        utils.execute('ln',
                      '--symbolic',
                      '--force',
                      '/dev/mapper/%s' % self.dev_name,
                      self.symlink_path,
                      run_as_root=True,
                      check_exit_code=True)
Beispiel #4
0
    def attach_volume(self, context, **kwargs):
        """Shadows the device and passes an unencrypted version to the
        instance.

        Transparent disk encryption is achieved by mounting the volume via
        dm-crypt and passing the resulting device to the instance. The
        instance is unaware of the underlying encryption due to modifying the
        original symbolic link to refer to the device mounted by dm-crypt.
        """

        key = self._get_key(context).get_encoded()
        passphrase = self._get_passphrase(key)

        try:
            self._open_volume(passphrase, **kwargs)
        except processutils.ProcessExecutionError as e:
            if e.exit_code == 1 and not is_luks(self.dev_path):
                # the device has never been formatted; format it and try again
                LOG.info(_LI("%s is not a valid LUKS device;"
                             " formatting device for first use"),
                         self.dev_path)
                self._format_volume(passphrase, **kwargs)
                self._open_volume(passphrase, **kwargs)
            else:
                raise

        # modify the original symbolic link to refer to the decrypted device
        utils.execute('ln', '--symbolic', '--force',
                      '/dev/mapper/%s' % self.dev_name, self.symlink_path,
                      run_as_root=True, check_exit_code=True)
Beispiel #5
0
def generate_winrm_x509_cert(user_id, bits=2048):
    """Generate a cert for passwordless auth for user in project."""
    subject = '/CN=%s' % user_id
    upn = '%s@localhost' % user_id

    with utils.tempdir() as tmpdir:
        keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
        conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf'))

        _create_x509_openssl_config(conffile, upn)

        (certificate, _err) = utils.execute(
             'openssl', 'req', '-x509', '-nodes', '-days', '3650',
             '-config', conffile, '-newkey', 'rsa:%s' % bits,
             '-outform', 'PEM', '-keyout', keyfile, '-subj', subject,
             '-extensions', 'v3_req_client',
             binary=True)

        (out, _err) = utils.execute('openssl', 'pkcs12', '-export',
                                    '-inkey', keyfile, '-password', 'pass:'******'ascii')
            certificate = certificate.decode('utf-8')

    return (private_key, certificate, fingerprint)
Beispiel #6
0
    def _make_vfat(self, path, tmpdir):
        # NOTE(mikal): This is a little horrible, but I couldn't find an
        # equivalent to genisoimage for vfat filesystems.
        with open(path, 'wb') as f:
            f.truncate(CONFIGDRIVESIZE_BYTES)

        utils.mkfs('vfat', path, label='config-2')

        with utils.tempdir() as mountdir:
            mounted = False
            try:
                _, err = utils.trycmd('mount',
                                      '-o',
                                      'loop,uid=%d,gid=%d' %
                                      (os.getuid(), os.getgid()),
                                      path,
                                      mountdir,
                                      run_as_root=True)
                if err:
                    raise exception.ConfigDriveMountFailed(operation='mount',
                                                           error=err)
                mounted = True

                # NOTE(mikal): I can't just use shutils.copytree here,
                # because the destination directory already
                # exists. This is annoying.
                for ent in os.listdir(tmpdir):
                    shutil.copytree(os.path.join(tmpdir, ent),
                                    os.path.join(mountdir, ent))

            finally:
                if mounted:
                    utils.execute('umount', mountdir, run_as_root=True)
Beispiel #7
0
    def _open_volume(self, passphrase, **kwargs):
        """Opens the LUKS partition on the volume using the specified
        passphrase.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("opening encrypted volume %s", self.dev_path)

        # NOTE(joel-coffman): cryptsetup will strip trailing newlines from
        # input specified on stdin unless --key-file=- is specified.
        cmd = ["cryptsetup", "create", "--key-file=-"]

        cipher = kwargs.get("cipher", None)
        if cipher is not None:
            cmd.extend(["--cipher", cipher])

        key_size = kwargs.get("key_size", None)
        if key_size is not None:
            cmd.extend(["--key-size", key_size])

        cmd.extend([self.dev_name, self.dev_path])

        utils.execute(*cmd,
                      process_input=passphrase,
                      check_exit_code=True,
                      run_as_root=True)
Beispiel #8
0
    def _format_volume(self, passphrase, **kwargs):
        """Creates a LUKS header on the volume.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("formatting encrypted volume %s", self.dev_path)

        # NOTE(joel-coffman): cryptsetup will strip trailing newlines from
        # input specified on stdin unless --key-file=- is specified.
        cmd = ["cryptsetup", "--batch-mode", "luksFormat", "--key-file=-"]

        cipher = kwargs.get("cipher", None)
        if cipher is not None:
            cmd.extend(["--cipher", cipher])

        key_size = kwargs.get("key_size", None)
        if key_size is not None:
            cmd.extend(["--key-size", key_size])

        cmd.extend([self.dev_path])

        utils.execute(*cmd,
                      process_input=passphrase,
                      check_exit_code=True,
                      run_as_root=True,
                      attempts=3)
Beispiel #9
0
    def _make_vfat(self, path, tmpdir):
        # NOTE(mikal): This is a little horrible, but I couldn't find an
        # equivalent to genisoimage for vfat filesystems.
        with open(path, 'wb') as f:
            f.truncate(CONFIGDRIVESIZE_BYTES)

        utils.mkfs('vfat', path, label='config-2')

        with utils.tempdir() as mountdir:
            mounted = False
            try:
                _, err = utils.trycmd(
                    'mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(),
                                                           os.getgid()),
                    path,
                    mountdir,
                    run_as_root=True)
                if err:
                    raise exception.ConfigDriveMountFailed(operation='mount',
                                                           error=err)
                mounted = True

                # NOTE(mikal): I can't just use shutils.copytree here,
                # because the destination directory already
                # exists. This is annoying.
                for ent in os.listdir(tmpdir):
                    shutil.copytree(os.path.join(tmpdir, ent),
                                    os.path.join(mountdir, ent))

            finally:
                if mounted:
                    utils.execute('umount', mountdir, run_as_root=True)
Beispiel #10
0
 def _close_volume(self, **kwargs):
     """Closes the device (effectively removes the dm-crypt mapping)."""
     LOG.debug("closing encrypted volume %s", self.dev_path)
     # cryptsetup returns 4 when attempting to destroy a non-active
     # dm-crypt device. We are going to ignore this error code to make
     # compute deleting that instance successfully.
     utils.execute('cryptsetup', 'remove', self.dev_name,
                   run_as_root=True, check_exit_code=[0, 4])
Beispiel #11
0
def ensure_ca_filesystem():
    """Ensure the CA filesystem exists."""
    ca_dir = ca_folder()
    if not os.path.exists(ca_path()):
        genrootca_sh_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'CA', 'genrootca.sh'))

        fileutils.ensure_tree(ca_dir)
        utils.execute("sh", genrootca_sh_path, cwd=ca_dir)
Beispiel #12
0
 def _close_volume(self, **kwargs):
     """Closes the device (effectively removes the dm-crypt mapping)."""
     LOG.debug("closing encrypted volume %s", self.dev_path)
     utils.execute('cryptsetup',
                   'luksClose',
                   self.dev_name,
                   run_as_root=True,
                   check_exit_code=True,
                   attempts=3)
Beispiel #13
0
def ensure_ca_filesystem():
    """Ensure the CA filesystem exists."""
    ca_dir = ca_folder()
    if not os.path.exists(ca_path()):
        genrootca_sh_path = os.path.abspath(
                os.path.join(os.path.dirname(__file__), 'CA', 'genrootca.sh'))

        fileutils.ensure_tree(ca_dir)
        utils.execute("sh", genrootca_sh_path, cwd=ca_dir)
Beispiel #14
0
def _ensure_project_folder(project_id):
    if not os.path.exists(ca_path(project_id)):
        geninter_sh_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'CA', 'geninter.sh'))
        utils.execute('sh',
                      geninter_sh_path,
                      project_id,
                      _project_cert_subject(project_id),
                      cwd=ca_folder())
Beispiel #15
0
def _convert_image(source, dest, in_format, out_format, run_as_root):
    cmd = ('qemu-img', 'convert', '-O', out_format, source, dest)
    if in_format is not None:
        cmd = cmd + ('-f', in_format)
    try:
        utils.execute(*cmd, run_as_root=run_as_root)
    except processutils.ProcessExecutionError as exp:
        msg = (_("Unable to convert image to %(format)s: %(exp)s") %
               {'format': out_format, 'exp': exp})
        raise exception.ImageUnacceptable(image_id=source, reason=msg)
Beispiel #16
0
    def _open_volume(self, passphrase, **kwargs):
        """Opens the LUKS partition on the volume using the specified
        passphrase.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("opening encrypted volume %s", self.dev_path)
        utils.execute('cryptsetup', 'luksOpen', '--key-file=-',
                      self.dev_path, self.dev_name, process_input=passphrase,
                      run_as_root=True, check_exit_code=True)
Beispiel #17
0
 def _close_volume(self, **kwargs):
     """Closes the device (effectively removes the dm-crypt mapping)."""
     LOG.debug("closing encrypted volume %s", self.dev_path)
     # cryptsetup returns 4 when attempting to destroy a non-active
     # dm-crypt device. We are going to ignore this error code to make
     # compute deleting that instance successfully.
     utils.execute('cryptsetup',
                   'remove',
                   self.dev_name,
                   run_as_root=True,
                   check_exit_code=[0, 4])
Beispiel #18
0
 def _xvp_start(self):
     if self._xvp_check_running():
         return
     LOG.debug('Starting xvp')
     try:
         utils.execute('xvp',
                       '-p', CONF.console_xvp_pid,
                       '-c', CONF.console_xvp_conf,
                       '-l', CONF.console_xvp_log)
     except processutils.ProcessExecutionError as err:
         LOG.error(_LE('Error starting xvp: %s'), err)
Beispiel #19
0
def _convert_image(source, dest, in_format, out_format, run_as_root):
    cmd = ('qemu-img', 'convert', '-O', out_format, source, dest)
    if in_format is not None:
        cmd = cmd + ('-f', in_format)
    try:
        utils.execute(*cmd, run_as_root=run_as_root)
    except processutils.ProcessExecutionError as exp:
        msg = (_("Unable to convert image to %(format)s: %(exp)s") % {
            'format': out_format,
            'exp': exp
        })
        raise exception.ImageUnacceptable(image_id=source, reason=msg)
Beispiel #20
0
def revoke_cert(project_id, file_name):
    """Revoke a cert by file name."""
    try:
        # NOTE(vish): potential race condition here
        utils.execute('openssl', 'ca', '-config', './openssl.cnf', '-revoke',
                      file_name, cwd=ca_folder(project_id))
        utils.execute('openssl', 'ca', '-gencrl', '-config', './openssl.cnf',
                      '-out', CONF.crl_file, cwd=ca_folder(project_id))
    except OSError:
        raise exception.ProjectNotFound(project_id=project_id)
    except processutils.ProcessExecutionError:
        raise exception.RevokeCertFailure(project_id=project_id)
Beispiel #21
0
    def _open_volume(self, passphrase, **kwargs):
        """Opens the LUKS partition on the volume using the specified
        passphrase.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("opening encrypted volume %s", self.dev_path)
        utils.execute('cryptsetup',
                      'luksOpen',
                      '--key-file=-',
                      self.dev_path,
                      self.dev_name,
                      process_input=passphrase,
                      run_as_root=True,
                      check_exit_code=True)
Beispiel #22
0
def generate_winrm_x509_cert(user_id, bits=2048):
    """Generate a cert for passwordless auth for user in project."""
    subject = '/CN=%s' % user_id
    upn = '%s@localhost' % user_id

    with utils.tempdir() as tmpdir:
        keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
        conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf'))

        _create_x509_openssl_config(conffile, upn)

        (certificate, _err) = utils.execute('openssl',
                                            'req',
                                            '-x509',
                                            '-nodes',
                                            '-days',
                                            '3650',
                                            '-config',
                                            conffile,
                                            '-newkey',
                                            'rsa:%s' % bits,
                                            '-outform',
                                            'PEM',
                                            '-keyout',
                                            keyfile,
                                            '-subj',
                                            subject,
                                            '-extensions',
                                            'v3_req_client',
                                            binary=True)

        (out, _err) = utils.execute('openssl',
                                    'pkcs12',
                                    '-export',
                                    '-inkey',
                                    keyfile,
                                    '-password',
                                    'pass:'******'ascii')
            certificate = certificate.decode('utf-8')

    return (private_key, certificate, fingerprint)
Beispiel #23
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    # NOTE(sirp): The config option import must go here to avoid an import
    # cycle
    CONF.import_opt('images_type', 'jacket.compute.virt.libvirt.imagebackend',
                    group='libvirt')
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") %
                {'path': path, 'exp': exp})
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") %
               {'path': path, 'error': err})
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
Beispiel #24
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    # NOTE(sirp): The config option import must go here to avoid an import
    # cycle
    CONF.import_opt('images_type',
                    'jacket.compute.virt.libvirt.imagebackend',
                    group='libvirt')
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") % {
            'path': path,
            'exp': exp
        })
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % {
            'path': path,
            'error': err
        })
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
Beispiel #25
0
    def test_encrypt_decrypt_x509(self):
        with utils.tempdir() as tmpdir:
            self.flags(ca_path=tmpdir)
            project_id = "fake"
            crypto.ensure_ca_filesystem()

            cert = crypto.fetch_ca(project_id)
            public_key = os.path.join(tmpdir, "public.pem")
            with open(public_key, 'w') as keyfile:
                keyfile.write(cert)

            text = "some @#!%^* test text"
            process_input = text.encode("ascii") if six.PY3 else text
            enc, _err = utils.execute('openssl',
                                     'rsautl',
                                     '-certin',
                                     '-encrypt',
                                     '-inkey', '%s' % public_key,
                                     process_input=process_input,
                                     binary=True)

            dec = crypto.decrypt_text(project_id, enc)
            self.assertIsInstance(dec, bytes)
            if six.PY3:
                dec = dec.decode('ascii')
            self.assertEqual(text, dec)
Beispiel #26
0
    def _xvp_encrypt(self, password, is_pool_password=False):
        """Call xvp to obfuscate passwords for config file.

        Args:
            - password: the password to encode, max 8 char for vm passwords,
                        and 16 chars for pool passwords. passwords will
                        be trimmed to max len before encoding.
            - is_pool_password: True if this is the XenServer api password
                                False if it's a VM console password
              (xvp uses different keys and max lengths for pool passwords)

        Note that xvp's obfuscation should not be considered 'real' encryption.
        It simply DES encrypts the passwords with static keys plainly viewable
        in the xvp source code.

        """
        maxlen = 8
        flag = '-e'
        if is_pool_password:
            maxlen = 16
            flag = '-x'
        # xvp will blow up on passwords that are too long (mdragon)
        password = password[:maxlen]
        out, err = utils.execute('xvp', flag, process_input=password)
        if err:
            raise processutils.ProcessExecutionError(_("Failed to run xvp."))
        return out.strip()
Beispiel #27
0
def is_luks(device):
    """Checks if the specified device uses LUKS for encryption.

    :param device: the device to check
    :returns: true if the specified device uses LUKS; false otherwise
    """
    try:
        # check to see if the device uses LUKS: exit status is 0
        # if the device is a LUKS partition and non-zero if not
        utils.execute('cryptsetup', 'isLuks', '--verbose', device,
                      run_as_root=True, check_exit_code=True)
        return True
    except processutils.ProcessExecutionError as e:
        LOG.warning(_LW("isLuks exited abnormally (status %(exit_code)s): "
                        "%(stderr)s"),
                    {"exit_code": e.exit_code, "stderr": e.stderr})
        return False
Beispiel #28
0
    def _is_crypt_device_available(self, dev_name):
        if not os.path.exists('/dev/mapper/%s' % dev_name):
            return False

        try:
            utils.execute('cryptsetup', 'status', dev_name, run_as_root=True)
        except processutils.ProcessExecutionError as e:
            # If /dev/mapper/<dev_name> is a non-crypt block device (such as a
            # normal disk or multipath device), exit_code will be 1. In the
            # case, we will omit the warning message.
            if e.exit_code != 1:
                LOG.warning(_LW('cryptsetup status %(dev_name) exited '
                                'abnormally (status %(exit_code)s): %(err)s'),
                            {"dev_name": dev_name, "exit_code": e.exit_code,
                             "err": e.stderr})
            return False
        return True
Beispiel #29
0
 def fping(ips):
     fping_ret = utils.execute(CONF.fping_path, *ips, check_exit_code=False)
     if not fping_ret:
         return set()
     alive_ips = set()
     for line in fping_ret[0].split("\n"):
         ip = line.split(" ", 1)[0]
         if "alive" in line:
             alive_ips.add(ip)
     return alive_ips
Beispiel #30
0
    def attach_volume(self, context, **kwargs):
        """Shadows the device and passes an unencrypted version to the
        instance.

        Transparent disk encryption is achieved by mounting the volume via
        dm-crypt and passing the resulting device to the instance. The
        instance is unaware of the underlying encryption due to modifying the
        original symbolic link to refer to the device mounted by dm-crypt.
        """

        key = self._get_key(context).get_encoded()
        passphrase = self._get_passphrase(key)

        self._open_volume(passphrase, **kwargs)

        # modify the original symbolic link to refer to the decrypted device
        utils.execute('ln', '--symbolic', '--force',
                      '/dev/mapper/%s' % self.dev_name, self.symlink_path,
                      run_as_root=True, check_exit_code=True)
Beispiel #31
0
def generate_x509_cert(user_id, project_id, bits=2048):
    """Generate and sign a cert for user in project."""
    subject = _user_cert_subject(user_id, project_id)

    with utils.tempdir() as tmpdir:
        keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
        csrfile = os.path.abspath(os.path.join(tmpdir, 'temp.csr'))
        utils.execute('openssl', 'genrsa', '-out', keyfile, str(bits))
        utils.execute('openssl', 'req', '-new', '-key', keyfile, '-out',
                      csrfile, '-batch', '-subj', subject)
        with open(keyfile) as f:
            private_key = f.read()
        with open(csrfile) as f:
            csr = f.read()

    (serial, signed_csr) = sign_csr(csr, project_id)
    fname = os.path.join(ca_folder(project_id), 'newcerts/%s.pem' % serial)
    cert = {'user_id': user_id, 'project_id': project_id, 'file_name': fname}
    db.certificate_create(context.get_admin_context(), cert)
    return (private_key, signed_csr)
Beispiel #32
0
 def fping(ips):
     fping_ret = utils.execute(CONF.fping_path, *ips,
                               check_exit_code=False)
     if not fping_ret:
         return set()
     alive_ips = set()
     for line in fping_ret[0].split("\n"):
         ip = line.split(" ", 1)[0]
         if "alive" in line:
             alive_ips.add(ip)
     return alive_ips
Beispiel #33
0
    def _is_crypt_device_available(self, dev_name):
        if not os.path.exists('/dev/mapper/%s' % dev_name):
            return False

        try:
            utils.execute('cryptsetup', 'status', dev_name, run_as_root=True)
        except processutils.ProcessExecutionError as e:
            # If /dev/mapper/<dev_name> is a non-crypt block device (such as a
            # normal disk or multipath device), exit_code will be 1. In the
            # case, we will omit the warning message.
            if e.exit_code != 1:
                LOG.warning(
                    _LW('cryptsetup status %(dev_name) exited '
                        'abnormally (status %(exit_code)s): %(err)s'), {
                            "dev_name": dev_name,
                            "exit_code": e.exit_code,
                            "err": e.stderr
                        })
            return False
        return True
Beispiel #34
0
    def _make_iso9660(self, path, tmpdir):
        publisher = "%(product)s %(version)s" % {
            'product': version.product_string(),
            'version': version.version_string_with_package()
            }

        utils.execute(CONF.mkisofs_cmd,
                      '-o', path,
                      '-ldots',
                      '-allow-lowercase',
                      '-allow-multidot',
                      '-l',
                      '-publisher',
                      publisher,
                      '-quiet',
                      '-J',
                      '-r',
                      '-V', 'config-2',
                      tmpdir,
                      attempts=1,
                      run_as_root=False)
Beispiel #35
0
def generate_x509_cert(user_id, project_id, bits=2048):
    """Generate and sign a cert for user in project."""
    subject = _user_cert_subject(user_id, project_id)

    with utils.tempdir() as tmpdir:
        keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
        csrfile = os.path.abspath(os.path.join(tmpdir, 'temp.csr'))
        utils.execute('openssl', 'genrsa', '-out', keyfile, str(bits))
        utils.execute('openssl', 'req', '-new', '-key', keyfile, '-out',
                      csrfile, '-batch', '-subj', subject)
        with open(keyfile) as f:
            private_key = f.read()
        with open(csrfile) as f:
            csr = f.read()

    (serial, signed_csr) = sign_csr(csr, project_id)
    fname = os.path.join(ca_folder(project_id), 'newcerts/%s.pem' % serial)
    cert = {'user_id': user_id,
            'project_id': project_id,
            'file_name': fname}
    db.certificate_create(context.get_admin_context(), cert)
    return (private_key, signed_csr)
Beispiel #36
0
    def test_create_configdrive_iso(self):
        CONF.set_override('config_drive_format', 'iso9660')
        imagefile = None

        try:
            self.mox.StubOutWithMock(utils, 'execute')

            utils.execute('genisoimage', '-o', mox.IgnoreArg(), '-ldots',
                          '-allow-lowercase', '-allow-multidot', '-l',
                          '-publisher', mox.IgnoreArg(), '-quiet', '-J', '-r',
                          '-V', 'config-2', mox.IgnoreArg(), attempts=1,
                          run_as_root=False).AndReturn(None)

            self.mox.ReplayAll()

            with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c:
                (fd, imagefile) = tempfile.mkstemp(prefix='cd_iso_')
                os.close(fd)
                c.make_drive(imagefile)

        finally:
            if imagefile:
                fileutils.delete_if_exists(imagefile)
Beispiel #37
0
def revoke_cert(project_id, file_name):
    """Revoke a cert by file name."""
    try:
        # NOTE(vish): potential race condition here
        utils.execute('openssl',
                      'ca',
                      '-config',
                      './openssl.cnf',
                      '-revoke',
                      file_name,
                      cwd=ca_folder(project_id))
        utils.execute('openssl',
                      'ca',
                      '-gencrl',
                      '-config',
                      './openssl.cnf',
                      '-out',
                      CONF.crl_file,
                      cwd=ca_folder(project_id))
    except OSError:
        raise exception.ProjectNotFound(project_id=project_id)
    except processutils.ProcessExecutionError:
        raise exception.RevokeCertFailure(project_id=project_id)
Beispiel #38
0
    def attach_volume(self, context, **kwargs):
        """Shadows the device and passes an unencrypted version to the
        instance.

        Transparent disk encryption is achieved by mounting the volume via
        dm-crypt and passing the resulting device to the instance. The
        instance is unaware of the underlying encryption due to modifying the
        original symbolic link to refer to the device mounted by dm-crypt.
        """

        key = self._get_key(context).get_encoded()
        passphrase = self._get_passphrase(key)

        self._open_volume(passphrase, **kwargs)

        # modify the original symbolic link to refer to the decrypted device
        utils.execute('ln',
                      '--symbolic',
                      '--force',
                      '/dev/mapper/%s' % self.dev_name,
                      self.symlink_path,
                      run_as_root=True,
                      check_exit_code=True)
Beispiel #39
0
    def _make_iso9660(self, path, tmpdir):
        publisher = "%(product)s %(version)s" % {
            'product': version.product_string(),
            'version': version.version_string_with_package()
        }

        utils.execute(CONF.mkisofs_cmd,
                      '-o',
                      path,
                      '-ldots',
                      '-allow-lowercase',
                      '-allow-multidot',
                      '-l',
                      '-publisher',
                      publisher,
                      '-quiet',
                      '-J',
                      '-r',
                      '-V',
                      'config-2',
                      tmpdir,
                      attempts=1,
                      run_as_root=False)
Beispiel #40
0
    def _format_volume(self, passphrase, **kwargs):
        """Creates a LUKS header on the volume.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("formatting encrypted volume %s", self.dev_path)

        # NOTE(joel-coffman): cryptsetup will strip trailing newlines from
        # input specified on stdin unless --key-file=- is specified.
        cmd = ["cryptsetup", "--batch-mode", "luksFormat", "--key-file=-"]

        cipher = kwargs.get("cipher", None)
        if cipher is not None:
            cmd.extend(["--cipher", cipher])

        key_size = kwargs.get("key_size", None)
        if key_size is not None:
            cmd.extend(["--key-size", key_size])

        cmd.extend([self.dev_path])

        utils.execute(*cmd, process_input=passphrase,
                      check_exit_code=True, run_as_root=True, attempts=3)
Beispiel #41
0
def _sign_csr(csr_text, ca_folder):
    with utils.tempdir() as tmpdir:
        inbound = os.path.join(tmpdir, 'inbound.csr')
        outbound = os.path.join(tmpdir, 'outbound.csr')

        try:
            with open(inbound, 'w') as csrfile:
                csrfile.write(csr_text)
        except IOError:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE('Failed to write inbound.csr'))

        LOG.debug('Flags path: %s', ca_folder)

        # Change working dir to CA
        fileutils.ensure_tree(ca_folder)
        utils.execute('openssl',
                      'ca',
                      '-batch',
                      '-out',
                      outbound,
                      '-config',
                      './openssl.cnf',
                      '-infiles',
                      inbound,
                      cwd=ca_folder)
        out, _err = utils.execute('openssl',
                                  'x509',
                                  '-in',
                                  outbound,
                                  '-serial',
                                  '-noout',
                                  cwd=ca_folder)
        serial = out.rpartition('=')[2].strip()

        with open(outbound, 'r') as crtfile:
            return (serial, crtfile.read())
Beispiel #42
0
 def _ssh_decrypt_text(self, ssh_private_key, text):
     with utils.tempdir() as tmpdir:
         sshkey = os.path.abspath(os.path.join(tmpdir, 'ssh.key'))
         with open(sshkey, 'w') as f:
             f.write(ssh_private_key)
         try:
             dec, _err = utils.execute('openssl',
                                       'rsautl',
                                       '-decrypt',
                                       '-inkey', sshkey,
                                       process_input=text,
                                       binary=True)
             return dec
         except processutils.ProcessExecutionError as exc:
             raise exception.DecryptionFailure(reason=exc.stderr)
Beispiel #43
0
def is_luks(device):
    """Checks if the specified device uses LUKS for encryption.

    :param device: the device to check
    :returns: true if the specified device uses LUKS; false otherwise
    """
    try:
        # check to see if the device uses LUKS: exit status is 0
        # if the device is a LUKS partition and non-zero if not
        utils.execute('cryptsetup',
                      'isLuks',
                      '--verbose',
                      device,
                      run_as_root=True,
                      check_exit_code=True)
        return True
    except processutils.ProcessExecutionError as e:
        LOG.warning(
            _LW("isLuks exited abnormally (status %(exit_code)s): "
                "%(stderr)s"), {
                    "exit_code": e.exit_code,
                    "stderr": e.stderr
                })
        return False
Beispiel #44
0
def _sign_csr(csr_text, ca_folder):
    with utils.tempdir() as tmpdir:
        inbound = os.path.join(tmpdir, 'inbound.csr')
        outbound = os.path.join(tmpdir, 'outbound.csr')

        try:
            with open(inbound, 'w') as csrfile:
                csrfile.write(csr_text)
        except IOError:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE('Failed to write inbound.csr'))

        LOG.debug('Flags path: %s', ca_folder)

        # Change working dir to CA
        fileutils.ensure_tree(ca_folder)
        utils.execute('openssl', 'ca', '-batch', '-out', outbound, '-config',
                      './openssl.cnf', '-infiles', inbound, cwd=ca_folder)
        out, _err = utils.execute('openssl', 'x509', '-in', outbound,
                                  '-serial', '-noout', cwd=ca_folder)
        serial = out.rpartition('=')[2].strip()

        with open(outbound, 'r') as crtfile:
            return (serial, crtfile.read())
Beispiel #45
0
    def _open_volume(self, passphrase, **kwargs):
        """Opens the LUKS partition on the volume using the specified
        passphrase.

        :param passphrase: the passphrase used to access the volume
        """
        LOG.debug("opening encrypted volume %s", self.dev_path)

        # NOTE(joel-coffman): cryptsetup will strip trailing newlines from
        # input specified on stdin unless --key-file=- is specified.
        cmd = ["cryptsetup", "create", "--key-file=-"]

        cipher = kwargs.get("cipher", None)
        if cipher is not None:
            cmd.extend(["--cipher", cipher])

        key_size = kwargs.get("key_size", None)
        if key_size is not None:
            cmd.extend(["--key-size", key_size])

        cmd.extend([self.dev_name, self.dev_path])

        utils.execute(*cmd, process_input=passphrase,
                      check_exit_code=True, run_as_root=True)
Beispiel #46
0
    def test_can_generate_x509(self, mock_create):
        with utils.tempdir() as tmpdir:
            self.flags(ca_path=tmpdir)
            crypto.ensure_ca_filesystem()
            _key, cert_str = crypto.generate_x509_cert('fake', 'fake')

            project_cert = crypto.fetch_ca(project_id='fake')

            signed_cert_file = os.path.join(tmpdir, "signed")
            with open(signed_cert_file, 'w') as keyfile:
                keyfile.write(cert_str)

            project_cert_file = os.path.join(tmpdir, "project")
            with open(project_cert_file, 'w') as keyfile:
                keyfile.write(project_cert)

            enc, err = utils.execute('openssl', 'verify', '-CAfile',
                    project_cert_file, '-verbose', signed_cert_file)
            self.assertFalse(err)
Beispiel #47
0
def _ensure_project_folder(project_id):
    if not os.path.exists(ca_path(project_id)):
        geninter_sh_path = os.path.abspath(
                os.path.join(os.path.dirname(__file__), 'CA', 'geninter.sh'))
        utils.execute('sh', geninter_sh_path, project_id,
                      _project_cert_subject(project_id), cwd=ca_folder())
Beispiel #48
0
 def _close_volume(self, **kwargs):
     """Closes the device (effectively removes the dm-crypt mapping)."""
     LOG.debug("closing encrypted volume %s", self.dev_path)
     utils.execute('cryptsetup', 'luksClose', self.dev_name,
                   run_as_root=True, check_exit_code=True,
                   attempts=3)