protected async Task Read_Archive_SpecialFiles_Async_Internal(TarEntryFormat format, TestTarFormat testFormat) { string testCaseName = "specialfiles"; await using (MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName)) { await using (TarReader reader = new TarReader(ms)) { if (testFormat is TestTarFormat.pax_gea) { TarEntry entry = await reader.GetNextEntryAsync(); VerifyGlobalExtendedAttributes(entry); } PosixTarEntry blockDevice = await reader.GetNextEntryAsync() as PosixTarEntry; VerifyBlockDeviceEntry(blockDevice, format, AssetBlockDeviceFileName); PosixTarEntry characterDevice = await reader.GetNextEntryAsync() as PosixTarEntry; VerifyCharacterDeviceEntry(characterDevice, format, AssetCharacterDeviceFileName); PosixTarEntry fifo = await reader.GetNextEntryAsync() as PosixTarEntry; VerifyFifoEntry(fifo, format, "fifofile"); Assert.Null(await reader.GetNextEntryAsync()); } } }
private void VerifyFifoEntry(PosixTarEntry fifo, TarEntryFormat format, string expectedFileName) { Assert.NotNull(fifo); VerifyType(fifo, format); Assert.True(fifo.Checksum > 0); Assert.Null(fifo.DataStream); Assert.Equal(TarEntryType.Fifo, fifo.EntryType); Assert.Equal(AssetGid, fifo.Gid); Assert.Equal(0, fifo.Length); Assert.Equal(DefaultLinkName, fifo.LinkName); Assert.Equal(AssetSpecialFileMode, fifo.Mode); Assert.True(fifo.ModificationTime > DateTimeOffset.UnixEpoch); Assert.Equal(expectedFileName, fifo.Name); Assert.Equal(AssetUid, fifo.Uid); Assert.Equal(DefaultDeviceMajor, fifo.DeviceMajor); Assert.Equal(DefaultDeviceMinor, fifo.DeviceMinor); Assert.Equal(AssetGName, fifo.GroupName); Assert.Equal(AssetUName, fifo.UserName); if (fifo is PaxTarEntry pax) { VerifyExtendedAttributeTimestamps(pax); } else if (fifo is GnuTarEntry gnu) { VerifyGnuTimestamps(gnu); } }
private void Verify_Archive_CharacterDevice(PosixTarEntry characterDevice, IReadOnlyDictionary <string, string> gea, string expectedFileName) { Assert.NotNull(characterDevice); Assert.Equal(TarEntryType.CharacterDevice, characterDevice.EntryType); Assert.True(characterDevice.Checksum > 0); Assert.Null(characterDevice.DataStream); Assert.Equal(AssetGid, characterDevice.Gid); Assert.Equal(0, characterDevice.Length); Assert.Equal(DefaultLinkName, characterDevice.LinkName); Assert.Equal(AssetSpecialFileMode, characterDevice.Mode); Assert.True(characterDevice.ModificationTime > DateTimeOffset.UnixEpoch); Assert.Equal(expectedFileName, characterDevice.Name); Assert.Equal(AssetUid, characterDevice.Uid); // TODO: Figure out why the numbers don't match https://github.com/dotnet/runtime/issues/68230 //Assert.Equal(AssetBlockDeviceMajor, characterDevice.DeviceMajor); //Assert.Equal(AssetBlockDeviceMinor, characterDevice.DeviceMinor); // Remove these two temporary checks when the above is fixed Assert.True(characterDevice.DeviceMajor > 0); Assert.True(characterDevice.DeviceMinor > 0); Assert.Equal(AssetGName, characterDevice.GroupName); Assert.Equal(AssetUName, characterDevice.UserName); if (characterDevice is PaxTarEntry pax) { // TODO: Check ext attrs https://github.com/dotnet/runtime/issues/68230 } else if (characterDevice is GnuTarEntry gnu) { Assert.True(gnu.AccessTime >= DateTimeOffset.UnixEpoch); Assert.True(gnu.ChangeTime >= DateTimeOffset.UnixEpoch); } }
protected void Read_Archive_SpecialFiles_Internal(TarEntryFormat format, TestTarFormat testFormat) { string testCaseName = "specialfiles"; using MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName); using TarReader reader = new TarReader(ms); if (testFormat is TestTarFormat.pax_gea) { VerifyGlobalExtendedAttributes(reader); } PosixTarEntry blockDevice = reader.GetNextEntry() as PosixTarEntry; VerifyBlockDeviceEntry(blockDevice, format, AssetBlockDeviceFileName); PosixTarEntry characterDevice = reader.GetNextEntry() as PosixTarEntry; VerifyCharacterDeviceEntry(characterDevice, format, AssetCharacterDeviceFileName); PosixTarEntry fifo = reader.GetNextEntry() as PosixTarEntry; VerifyFifoEntry(fifo, format, "fifofile"); Assert.Null(reader.GetNextEntry()); }
public async Task SpecialFile_Unelevated_Throws_Async() { using (TempDirectory root = new TempDirectory()) await using (MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, TestTarFormat.ustar, "specialfiles")) await using (TarReader reader = new TarReader(ms)) { string path = Path.Join(root.Path, "output"); // Block device requires elevation for writing PosixTarEntry blockDevice = await reader.GetNextEntryAsync() as PosixTarEntry; Assert.NotNull(blockDevice); await Assert.ThrowsAsync <UnauthorizedAccessException>(() => blockDevice.ExtractToFileAsync(path, overwrite: false)); Assert.False(File.Exists(path)); // Character device requires elevation for writing PosixTarEntry characterDevice = await reader.GetNextEntryAsync() as PosixTarEntry; Assert.NotNull(characterDevice); await Assert.ThrowsAsync <UnauthorizedAccessException>(() => characterDevice.ExtractToFileAsync(path, overwrite: false)); Assert.False(File.Exists(path)); // Fifo does not require elevation, should succeed PosixTarEntry fifo = await reader.GetNextEntryAsync() as PosixTarEntry; Assert.NotNull(fifo); await fifo.ExtractToFileAsync(path, overwrite : false); Assert.True(File.Exists(path)); Assert.Null(await reader.GetNextEntryAsync()); } }
private void Verify_Archive_Fifo(PosixTarEntry fifo, IReadOnlyDictionary <string, string> gea, string expectedFileName) { Assert.NotNull(fifo); Assert.True(fifo.Checksum > 0); Assert.Null(fifo.DataStream); Assert.Equal(TarEntryType.Fifo, fifo.EntryType); Assert.Equal(AssetGid, fifo.Gid); Assert.Equal(0, fifo.Length); Assert.Equal(DefaultLinkName, fifo.LinkName); Assert.Equal(AssetSpecialFileMode, fifo.Mode); Assert.True(fifo.ModificationTime > DateTimeOffset.UnixEpoch); Assert.Equal(expectedFileName, fifo.Name); Assert.Equal(AssetUid, fifo.Uid); Assert.Equal(DefaultDeviceMajor, fifo.DeviceMajor); Assert.Equal(DefaultDeviceMinor, fifo.DeviceMinor); Assert.Equal(AssetGName, fifo.GroupName); Assert.Equal(AssetUName, fifo.UserName); if (fifo is PaxTarEntry pax) { // TODO: Check ext attrs https://github.com/dotnet/runtime/issues/68230 } else if (fifo is GnuTarEntry gnu) { Assert.True(gnu.AccessTime >= DateTimeOffset.UnixEpoch); Assert.True(gnu.ChangeTime >= DateTimeOffset.UnixEpoch); } }
private void SetFifoProperties(PosixTarEntry fifo) { Assert.NotNull(fifo); Assert.Equal(TarEntryType.Fifo, fifo.EntryType); SetCommonProperties(fifo); SetPosixProperties(fifo); }
protected void SetPosixProperties(PosixTarEntry entry) { Assert.Equal(DefaultGName, entry.GroupName); entry.GroupName = TestGName; Assert.Equal(DefaultUName, entry.UserName); entry.UserName = TestUName; }
protected void VerifyPosixProperties(PosixTarEntry entry) { entry.GroupName = TestGName; Assert.Equal(TestGName, entry.GroupName); entry.UserName = TestUName; Assert.Equal(TestUName, entry.UserName); }
protected void VerifyPosixFifo(PosixTarEntry fifo) { Assert.NotNull(fifo); Assert.Equal(TarEntryType.Fifo, fifo.EntryType); VerifyCommonProperties(fifo); VerifyPosixProperties(fifo); VerifyUnsupportedDeviceProperties(fifo); VerifyUnsupportedLinkProperty(fifo); VerifyUnsupportedDataStream(fifo); }
protected void VerifyUnsupportedDeviceProperties(PosixTarEntry entry) { Assert.True(entry.EntryType is not TarEntryType.CharacterDevice and not TarEntryType.BlockDevice); Assert.Equal(0, entry.DeviceMajor); Assert.Throws <InvalidOperationException>(() => entry.DeviceMajor = 5); Assert.Equal(0, entry.DeviceMajor); // No change Assert.Equal(0, entry.DeviceMinor); Assert.Throws <InvalidOperationException>(() => entry.DeviceMinor = 5); Assert.Equal(0, entry.DeviceMinor); // No change }
protected void VerifyPosixBlockDevice(PosixTarEntry device) { Assert.NotNull(device); Assert.Equal(TarEntryType.BlockDevice, device.EntryType); VerifyCommonProperties(device); VerifyUnsupportedLinkProperty(device); VerifyUnsupportedDataStream(device); Assert.Equal(TestBlockDeviceMajor, device.DeviceMajor); Assert.Equal(TestBlockDeviceMinor, device.DeviceMinor); }
public void Add_BlockDevice_Async(TarEntryFormat format) { RemoteExecutor.Invoke(async(string strFormat) => { TarEntryFormat expectedFormat = Enum.Parse <TarEntryFormat>(strFormat); using (TempDirectory root = new TempDirectory()) { string blockDevicePath = Path.Join(root.Path, AssetBlockDeviceFileName); // Creating device files needs elevation Interop.CheckIo(Interop.Sys.CreateBlockDevice(blockDevicePath, (int)DefaultMode, TestBlockDeviceMajor, TestBlockDeviceMinor)); await using (MemoryStream archive = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archive, expectedFormat, leaveOpen: true)) { await writer.WriteEntryAsync(fileName: blockDevicePath, entryName: AssetBlockDeviceFileName); } archive.Seek(0, SeekOrigin.Begin); await using (TarReader reader = new TarReader(archive)) { PosixTarEntry entry = await reader.GetNextEntryAsync() as PosixTarEntry; Assert.Equal(expectedFormat, entry.Format); Assert.NotNull(entry); Assert.Equal(AssetBlockDeviceFileName, entry.Name); Assert.Equal(DefaultLinkName, entry.LinkName); Assert.Equal(TarEntryType.BlockDevice, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(blockDevicePath, entry); Assert.Equal(TestBlockDeviceMajor, entry.DeviceMajor); Assert.Equal(TestBlockDeviceMinor, entry.DeviceMinor); Assert.Null(await reader.GetNextEntryAsync()); } } } }, format.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose(); }
public void Add_BlockDevice(TarFormat format) { RemoteExecutor.Invoke((string strFormat) => { TarFormat expectedFormat = Enum.Parse <TarFormat>(strFormat); using TempDirectory root = new TempDirectory(); string blockDevicePath = Path.Join(root.Path, AssetBlockDeviceFileName); // Creating device files needs elevation Interop.CheckIo(Interop.Sys.CreateBlockDevice(blockDevicePath, (int)DefaultMode, TestBlockDeviceMajor, TestBlockDeviceMinor)); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, expectedFormat, leaveOpen: true)) { writer.WriteEntry(fileName: blockDevicePath, entryName: AssetBlockDeviceFileName); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { Assert.Equal(TarFormat.Unknown, reader.Format); PosixTarEntry entry = reader.GetNextEntry() as PosixTarEntry; Assert.Equal(expectedFormat, reader.Format); Assert.NotNull(entry); Assert.Equal(AssetBlockDeviceFileName, entry.Name); Assert.Equal(DefaultLinkName, entry.LinkName); Assert.Equal(TarEntryType.BlockDevice, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(blockDevicePath, entry); // TODO: Fix how these values are collected, the numbers don't match even though https://github.com/dotnet/runtime/issues/68230 // they come from stat's dev and from the major/minor syscalls // Assert.Equal(TestBlockDeviceMajor, entry.DeviceMajor); // Assert.Equal(TestBlockDeviceMinor, entry.DeviceMinor); Assert.Null(reader.GetNextEntry()); } }, format.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose(); }
private void SetCharacterDeviceProperties(PosixTarEntry device) { Assert.NotNull(device); Assert.Equal(TarEntryType.CharacterDevice, device.EntryType); SetCommonProperties(device); SetPosixProperties(device); // DeviceMajor Assert.Equal(DefaultDeviceMajor, device.DeviceMajor); Assert.Throws <ArgumentOutOfRangeException>(() => device.DeviceMajor = -1); Assert.Throws <ArgumentOutOfRangeException>(() => device.DeviceMajor = 2097152); device.DeviceMajor = TestCharacterDeviceMajor; // DeviceMinor Assert.Equal(DefaultDeviceMinor, device.DeviceMinor); Assert.Throws <ArgumentOutOfRangeException>(() => device.DeviceMinor = -1); Assert.Throws <ArgumentOutOfRangeException>(() => device.DeviceMinor = 2097152); device.DeviceMinor = TestCharacterDeviceMinor; }
public void Add_Fifo_Async(TarEntryFormat format) { RemoteExecutor.Invoke(async(string strFormat) => { TarEntryFormat expectedFormat = Enum.Parse <TarEntryFormat>(strFormat); using (TempDirectory root = new TempDirectory()) { string fifoName = "fifofile"; string fifoPath = Path.Join(root.Path, fifoName); Interop.CheckIo(Interop.Sys.MkFifo(fifoPath, (int)DefaultMode)); await using (MemoryStream archive = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archive, expectedFormat, leaveOpen: true)) { await writer.WriteEntryAsync(fileName: fifoPath, entryName: fifoName); } archive.Seek(0, SeekOrigin.Begin); await using (TarReader reader = new TarReader(archive)) { PosixTarEntry entry = await reader.GetNextEntryAsync() as PosixTarEntry; Assert.Equal(expectedFormat, entry.Format); Assert.NotNull(entry); Assert.Equal(fifoName, entry.Name); Assert.Equal(DefaultLinkName, entry.LinkName); Assert.Equal(TarEntryType.Fifo, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(fifoPath, entry); Assert.Null(await reader.GetNextEntryAsync()); } } } }, format.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose(); }
private (string, string, PosixTarEntry) Prepare_Extract_SpecialFiles(TempDirectory root, TarEntryFormat format, TarEntryType entryType) { string entryName = entryType.ToString(); string destination = Path.Join(root.Path, entryName); PosixTarEntry entry = InvokeTarEntryCreationConstructor(format, entryType, entryName) as PosixTarEntry; Assert.NotNull(entry); if (entryType is TarEntryType.BlockDevice) { entry.DeviceMajor = TestBlockDeviceMajor; entry.DeviceMinor = TestBlockDeviceMinor; } else if (entryType is TarEntryType.CharacterDevice) { entry.DeviceMajor = TestCharacterDeviceMajor; entry.DeviceMinor = TestCharacterDeviceMinor; } return(entryName, destination, entry); }
public void Read_Archive_SpecialFiles(TarFormat format, TestTarFormat testFormat) { string testCaseName = "specialfiles"; using MemoryStream ms = GetTarMemoryStream(CompressionMethod.Uncompressed, testFormat, testCaseName); using TarReader reader = new TarReader(ms); if (testFormat == TestTarFormat.pax_gea) { // The GEA are collected after reading the first entry, not on the constructor Assert.Null(reader.GlobalExtendedAttributes); } // Format is determined after reading the first entry, not on the constructor Assert.Equal(TarFormat.Unknown, reader.Format); PosixTarEntry blockDevice = reader.GetNextEntry() as PosixTarEntry; Assert.Equal(format, reader.Format); if (testFormat == TestTarFormat.pax_gea) { Assert.NotNull(reader.GlobalExtendedAttributes); Assert.True(reader.GlobalExtendedAttributes.Any()); Assert.Contains(AssetPaxGeaKey, reader.GlobalExtendedAttributes); Assert.Equal(AssetPaxGeaValue, reader.GlobalExtendedAttributes[AssetPaxGeaKey]); } Verify_Archive_BlockDevice(blockDevice, reader.GlobalExtendedAttributes, AssetBlockDeviceFileName); PosixTarEntry characterDevice = reader.GetNextEntry() as PosixTarEntry; Verify_Archive_CharacterDevice(characterDevice, reader.GlobalExtendedAttributes, AssetCharacterDeviceFileName); PosixTarEntry fifo = reader.GetNextEntry() as PosixTarEntry; Verify_Archive_Fifo(fifo, reader.GlobalExtendedAttributes, "fifofile"); Assert.Null(reader.GetNextEntry()); }
private void Verify_Extract_SpecialFiles(string destination, PosixTarEntry entry, TarEntryType entryType) { Assert.True(File.Exists(destination)); Interop.Sys.FileStatus status = default; status.Mode = default; status.Dev = default; Interop.CheckIo(Interop.Sys.LStat(destination, out status)); int fileType = status.Mode & Interop.Sys.FileTypes.S_IFMT; if (entryType is TarEntryType.BlockDevice) { Assert.Equal(Interop.Sys.FileTypes.S_IFBLK, fileType); } else if (entryType is TarEntryType.CharacterDevice) { Assert.Equal(Interop.Sys.FileTypes.S_IFCHR, fileType); } else if (entryType is TarEntryType.Fifo) { Assert.Equal(Interop.Sys.FileTypes.S_IFIFO, fileType); } if (entryType is TarEntryType.BlockDevice or TarEntryType.CharacterDevice) { uint major; uint minor; unsafe { Interop.Sys.GetDeviceIdentifiers((ulong)status.RDev, &major, &minor); } Assert.Equal((int)major, entry.DeviceMajor); Assert.Equal((int)minor, entry.DeviceMinor); } AssertFileModeEquals(destination, TestPermission1); }
protected void VerifyPosixSymbolicLink(PosixTarEntry symbolicLink) { VerifyCommonSymbolicLink(symbolicLink); VerifyUnsupportedDeviceProperties(symbolicLink); }
protected void VerifyPosixRegularFile(PosixTarEntry regularFile, bool isWritable) { VerifyCommonRegularFile(regularFile, isWritable); VerifyUnsupportedDeviceProperties(regularFile); }
protected void VerifyPosixDirectory(PosixTarEntry directory) { VerifyCommonDirectory(directory); VerifyUnsupportedDeviceProperties(directory); }
protected void VerifyPosixHardLink(PosixTarEntry hardLink) { VerifyCommonHardLink(hardLink); VerifyUnsupportedDeviceProperties(hardLink); }