Example #1
0
def write_tpm_data(vm_id, tpm_data):
    """
    Write TPM data for the given VM.

    :param vm_id: VM id
    :type vm_id: string
    :param tpm_data: encoded TPM data as previously obtained from
      `read_tpm_data()`
    :type tpm_data: ProtectedPassword
    """
    tpm_data = password.unprotect(tpm_data)
    # Permit only archives with plain files and directories to prevent various
    # kinds of attacks.
    with tempfile.TemporaryDirectory() as d:
        accessor = filedata.DirectoryData(os.path.join(d, 'check'))
        accessor.store(tpm_data)
        for root, dirs, files in os.walk(d):
            for f in files:
                path = os.path.join(root, f)
                if not os.path.isfile(path):
                    logging.error("Special file in TPM data: %s", path)
                    raise exception.ExternalDataFailed(
                        reason="Cannot write TPM data with non-regular files",
                        path=path)
    # OK, write the data to the target location
    accessor = filedata.DirectoryData(filedata.tpm_path(vm_id))
    accessor.store(tpm_data)
Example #2
0
def test_directory_data_no_data():
    # no directory
    data = filedata.DirectoryData('/this-directory-must-not-exist')
    with pytest.raises(exception.ExternalDataFailed):
        data.retrieve()
    # directory empty
    with tempfile.TemporaryDirectory() as d:
        data = filedata.DirectoryData(d, allow_empty=False)
        with pytest.raises(exception.ExternalDataFailed):
            data.retrieve()
        data = filedata.DirectoryData(d, allow_empty=True)
        assert data.retrieve() is not None
Example #3
0
def test_supervdsm_symlink(monkeypatch):
    with directory_data(monkeypatch) as d:
        os.symlink('/foo', os.path.join(d.directory, 'bar'))
        encoded = filedata.DirectoryData(d.directory).retrieve()
    with temporary_directory(monkeypatch):
        with pytest.raises(exception.ExternalDataFailed):
            virt.write_tpm_data(UUID, encoded)
Example #4
0
def test_directory_data_read_write():
    with directory_data() as d:
        data = filedata.DirectoryData(d.directory)
        encoded = data.retrieve()
        assert encoded is not None
    with temporary_directory() as d:
        data = filedata.DirectoryData(d.directory)
        data.store(encoded)
        assert open(d.path).read() == FILE_DATA
        assert open(d.subpath).read() == FILE_DATA_2
        n = 0
        for _root, _dirs, files in os.walk(d.directory):
            n += len(files)
        assert n == 2
        permissions = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
        assert os.stat(d.directory).st_mode & permissions == DIRECTORY_MODE
Example #5
0
def data_retriever(directory):
    data = filedata.DirectoryData(directory)

    def retriever(last_modified):
        encoded = data.retrieve(last_modified=last_modified)
        return encoded, data.last_modified()

    return retriever
Example #6
0
def test_directory_data_rewrite():
    with directory_data() as d:
        data = filedata.DirectoryData(d.directory)
        encoded = data.retrieve()
    with temporary_directory() as d:
        os.mkdir(d.directory)
        old_path = os.path.join(d.directory, 'old')
        open(old_path, 'w').write("invalid")
        open(d.path, 'w').write("invalid")
        data = filedata.DirectoryData(d.directory)
        data.store(encoded)
        assert not os.path.exists(old_path)
        assert open(d.path).read() == FILE_DATA
        assert open(d.subpath).read() == FILE_DATA_2
        n = 0
        for _root, _dirs, files in os.walk(d.directory):
            n += len(files)
        assert n == 2
Example #7
0
def test_monitor_read():
    with directory_data() as d:
        monitor = filedata.Monitor(data_retriever(d.directory))
        encoded = monitor.data()
        assert encoded is not None
    with temporary_directory() as d:
        data = filedata.DirectoryData(d.directory)
        data.store(encoded)
        assert open(d.path).read() == FILE_DATA
        assert open(d.subpath).read() == FILE_DATA_2
        n = 0
        for _root, _dirs, files in os.walk(d.directory):
            n += len(files)
        assert n == 2
Example #8
0
def read_tpm_data(vm_id, last_modified):
    """
    Return TPM data of the given VM.

    If data is not newer than `last_modified`, return None.
    In addition to data, the last detected data modification time is
    returned; the returned data may be newer, but never older than the
    returned time.

    :param vm_id: VM id
    :type vm_id: string
    :param last_modified: if data file system time stamp is not
      newer than this time in seconds, None is returned
    :type last_modified: float
    :returns: tuple (DATA, MODIFIED) where DATA is encoded TPM data suitable to
      use in `write_tpm_data()`, wrapped by `password.ProtectedPassword`,
      or None, and MODIFIED is DATA modification time (which may be older than
      actual modification time)
    :rtype: tuple
    """
    accessor = filedata.DirectoryData(filedata.tpm_path(vm_id), compress=False)
    currently_modified = accessor.last_modified()
    data = accessor.retrieve(last_modified=last_modified)
    return password.ProtectedPassword(data), currently_modified
Example #9
0
def test_directory_data_modified():
    with directory_data() as d:
        data = filedata.DirectoryData(d.directory)
        data.retrieve()
        assert data.last_modified() == \
            max(os.stat(d.path).st_mtime, os.stat(d.subpath).st_mtime)