Esempio n. 1
0
        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());
                }
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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());
                    }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
 private void SetFifoProperties(PosixTarEntry fifo)
 {
     Assert.NotNull(fifo);
     Assert.Equal(TarEntryType.Fifo, fifo.EntryType);
     SetCommonProperties(fifo);
     SetPosixProperties(fifo);
 }
Esempio n. 8
0
        protected void SetPosixProperties(PosixTarEntry entry)
        {
            Assert.Equal(DefaultGName, entry.GroupName);
            entry.GroupName = TestGName;

            Assert.Equal(DefaultUName, entry.UserName);
            entry.UserName = TestUName;
        }
Esempio n. 9
0
        protected void VerifyPosixProperties(PosixTarEntry entry)
        {
            entry.GroupName = TestGName;
            Assert.Equal(TestGName, entry.GroupName);

            entry.UserName = TestUName;
            Assert.Equal(TestUName, entry.UserName);
        }
Esempio n. 10
0
 protected void VerifyPosixFifo(PosixTarEntry fifo)
 {
     Assert.NotNull(fifo);
     Assert.Equal(TarEntryType.Fifo, fifo.EntryType);
     VerifyCommonProperties(fifo);
     VerifyPosixProperties(fifo);
     VerifyUnsupportedDeviceProperties(fifo);
     VerifyUnsupportedLinkProperty(fifo);
     VerifyUnsupportedDataStream(fifo);
 }
Esempio n. 11
0
        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
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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();
        }
Esempio n. 14
0
        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();
        }
Esempio n. 15
0
        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;
        }
Esempio n. 16
0
        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();
        }
Esempio n. 17
0
        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);
        }
Esempio n. 18
0
        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());
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
 protected void VerifyPosixSymbolicLink(PosixTarEntry symbolicLink)
 {
     VerifyCommonSymbolicLink(symbolicLink);
     VerifyUnsupportedDeviceProperties(symbolicLink);
 }
Esempio n. 21
0
 protected void VerifyPosixRegularFile(PosixTarEntry regularFile, bool isWritable)
 {
     VerifyCommonRegularFile(regularFile, isWritable);
     VerifyUnsupportedDeviceProperties(regularFile);
 }
Esempio n. 22
0
 protected void VerifyPosixDirectory(PosixTarEntry directory)
 {
     VerifyCommonDirectory(directory);
     VerifyUnsupportedDeviceProperties(directory);
 }
Esempio n. 23
0
 protected void VerifyPosixHardLink(PosixTarEntry hardLink)
 {
     VerifyCommonHardLink(hardLink);
     VerifyUnsupportedDeviceProperties(hardLink);
 }