Example #1
0
def generate_key_file(filename, size=DEFAULT_KEY_SIZE, context=None):
    """
    Generate a file with random contents that can be used as a key file.

    :param filename: The pathname of the key file (a string).
    :param size: How large the key file should be (see :func:`.coerce_size()`,
                 defaults to :data:`DEFAULT_KEY_SIZE`).
    :param context: An execution context created by :mod:`executor.contexts`
                    (coerced using :func:`.coerce_context()`).
    :raises: :exc:`~executor.ExternalCommandFailed` when the command fails.
    """
    context = coerce_context(context)
    size = coerce_size(size)
    logger.debug("Creating key file of %i bytes: %s", size, filename)
    context.execute(
        'dd',
        'if=/dev/urandom',
        'of=%s' % filename,
        'bs=%i' % size,
        'count=1',
        # I'd rather use `status=none' then silent=True, however the
        # `status=none' flag isn't supported on Ubuntu 12.04 which
        # currently runs on Travis CI, so there you go :-p.
        silent=True,
        sudo=True,
    )
    context.execute('chown', 'root:root', filename, sudo=True)
    context.execute('chmod', '400', filename, sudo=True)
Example #2
0
    def cryptdisks_start_helper(self, emulated):
        """
        Test cryptdisks_start integration and emulation.

        This test requires the following line to be present in ``/etc/crypttab``::

         linux-utils /tmp/linux-utils.img /tmp/linux-utils.key discard,luks,noauto,readonly,tries=1
        """
        if not any(entry.target == TEST_TARGET_NAME and entry.source ==
                   TEST_IMAGE_FILE and entry.key_file == TEST_KEY_FILE
                   and 'luks' in entry.options for entry in parse_crypttab()):
            return self.skipTest(
                "/etc/crypttab isn't set up to test cryptdisks_start!")
        context = LocalContext()
        if emulated:
            # Disable the use of the `cryptdisks_start' program.
            context.find_program = MagicMock(return_value=[])
        # Generate the key file.
        with TemporaryKeyFile(filename=TEST_KEY_FILE):
            # Create the image file and the encrypted filesystem.
            create_image_file(filename=TEST_IMAGE_FILE,
                              size=coerce_size('10 MiB'))
            create_encrypted_filesystem(device_file=TEST_IMAGE_FILE,
                                        key_file=TEST_KEY_FILE)
            # Make sure the mapped device file doesn't exist yet.
            assert not os.path.exists(TEST_TARGET_DEVICE)
            # Unlock the encrypted filesystem using `cryptdisks_start'.
            if emulated:
                cryptdisks_start(context=context, target=TEST_TARGET_NAME)
            else:
                returncode, output = run_cli(cryptdisks_start_cli,
                                             TEST_TARGET_NAME)
                assert returncode == 0
            # Make sure the mapped device file has appeared.
            assert os.path.exists(TEST_TARGET_DEVICE)
            # Unlock the encrypted filesystem again (this should be a no-op).
            cryptdisks_start(context=context, target=TEST_TARGET_NAME)
            # Make sure the mapped device file still exists.
            assert os.path.exists(TEST_TARGET_DEVICE)
            # Lock the filesystem before we finish.
            if emulated:
                cryptdisks_stop(context=context, target=TEST_TARGET_NAME)
            else:
                returncode, output = run_cli(cryptdisks_stop_cli,
                                             TEST_TARGET_NAME)
                assert returncode == 0
            # Make sure the mapped device file has disappeared.
            assert not os.path.exists(TEST_TARGET_DEVICE)
            # Lock the filesystem again (this should be a no-op).
            cryptdisks_stop(context=context, target=TEST_TARGET_NAME)
            # Make sure the mapped device file is still gone.
            assert not os.path.exists(TEST_TARGET_DEVICE)
            # Test the error handling.
            for function in cryptdisks_start, cryptdisks_stop:
                self.assertRaises(
                    ValueError if emulated else ExternalCommandFailed,
                    function,
                    context=context,
                    target=TEST_UNKNOWN_TARGET,
                )
Example #3
0
 def test_create_encrypted_filesystem(self):
     """Test creation of encrypted filesystems."""
     with TemporaryKeyFile(filename=TEST_KEY_FILE):
         create_image_file(filename=TEST_IMAGE_FILE,
                           size=coerce_size('10 MiB'))
         create_encrypted_filesystem(device_file=TEST_IMAGE_FILE,
                                     key_file=TEST_KEY_FILE)
         assert 'LUKS' in execute('file', TEST_IMAGE_FILE, capture=True)
Example #4
0
 def test_create_image_file(self):
     """Test image file creation."""
     size = coerce_size('1 MiB')
     create_image_file(TEST_IMAGE_FILE, size)
     # Make sure the image file was created with the correct size.
     assert os.path.getsize(TEST_IMAGE_FILE) == size
     # Make sure the contents of the image file are zero bytes.
     with open(TEST_IMAGE_FILE, 'rb') as handle:
         for byte in iter(functools.partial(handle.read, 1), b''):
             assert byte == b'\x00'
Example #5
0
 def test_unlock_encrypted_filesystem(self):
     """Test unlocking of encrypted filesystems."""
     with TemporaryKeyFile(filename=TEST_KEY_FILE):
         create_image_file(filename=TEST_IMAGE_FILE,
                           size=coerce_size('10 MiB'))
         create_encrypted_filesystem(device_file=TEST_IMAGE_FILE,
                                     key_file=TEST_KEY_FILE)
         unlock_filesystem(device_file=TEST_IMAGE_FILE,
                           target=TEST_TARGET_NAME,
                           key_file=TEST_KEY_FILE)
         assert os.path.exists(os.path.join('/dev/mapper',
                                            TEST_TARGET_NAME))
         lock_filesystem(target=TEST_TARGET_NAME)
         assert not os.path.exists(
             os.path.join('/dev/mapper', TEST_TARGET_NAME))
Example #6
0
 def test_generate_key_file(self):
     """Test key file generation."""
     context = LocalContext(sudo=True)
     size = coerce_size('4 KiB')
     with TemporaryKeyFile(context=context,
                           filename=TEST_KEY_FILE,
                           size=size):
         # Make sure the key file was created with the correct size.
         assert os.path.getsize(TEST_KEY_FILE) == size
         # Ensure that the key file contains some randomness.
         cat = context.execute('cat', TEST_KEY_FILE, capture=True)
         random_bytes = set(cat.stdout)
         # Although I know that (by definition of randomness) the following
         # assertion can fail I nevertheless feel that it adds value :-p.
         assert len(random_bytes) > 10
Example #7
0
def create_image_file(filename, size, context=None):
    r"""
    Create an image file filled with bytes containing zero (``\0``).

    :param filename: The pathname of the image file (a string).
    :param size: How large the image file should be (see :func:`.coerce_size()`).
    :param context: See :func:`.coerce_context()` for details.
    :raises: :exc:`~exceptions.ValueError` when `size` is invalid,
             :exc:`~executor.ExternalCommandFailed` when the command fails.
    """
    context = coerce_context(context)
    size = coerce_size(size)
    logger.debug("Creating image file of %i bytes: %s", size, filename)
    head_command = 'head --bytes=%i /dev/zero > %s'
    context.execute(head_command % (size, quote(filename)), shell=True, tty=False)
Example #8
0
 def test_coerce_size(self):
     """Test coercion of data sizes."""
     assert coerce_size(1) == 1
     assert coerce_size('5 KiB') == 5120
     self.assertRaises(ValueError, coerce_size, None)