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