private static UnixFileMode DetermineUMask() { // To determine the umask, we'll create a file with full permissions and see // what gets filtered out. // note: only the owner of a file, and root can change file permissions. const UnixFileMode OwnershipPermissions = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute; string filename = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); FileStreamOptions options = new() { Mode = FileMode.CreateNew, UnixCreateMode = OwnershipPermissions, Options = FileOptions.DeleteOnClose, Access = FileAccess.Write, BufferSize = 0 }; using var fs = new FileStream(filename, options); UnixFileMode actual = File.GetUnixFileMode(fs.SafeFileHandle); return(OwnershipPermissions & ~actual); }
private void SetUnixFileMode(SafeFileHandle?handle, string?path, UnixFileMode mode) { if ((mode & ~FileSystem.ValidUnixFileModes) != 0) { throw new ArgumentException(SR.Arg_InvalidUnixFileMode, nameof(UnixFileMode)); } // Use ThrowNotFound to throw the appropriate exception when the file doesn't exist. if (handle is null && path is not null) { EnsureCachesInitialized(path); if (!EntryExists || IsBrokenLink) { FileSystemInfo.ThrowNotFound(path); } } // Linux does not support link permissions. // To have consistent cross-platform behavior we operate on the link target. int rv = handle is not null?Interop.Sys.FChMod(handle, (int)mode) : Interop.Sys.ChMod(path !, (int)mode); Interop.CheckIo(rv, path); InvalidateCaches(); }
protected void VerifyPlatformSpecificMetadata(string filePath, TarEntry entry) { Assert.True(entry.ModificationTime > DateTimeOffset.UnixEpoch); UnixFileMode expectedMode = DefaultWindowsMode; Assert.Equal(expectedMode, entry.Mode); Assert.Equal(DefaultUid, entry.Uid); Assert.Equal(DefaultGid, entry.Gid); if (entry is PosixTarEntry posix) { Assert.Equal(DefaultGName, posix.GroupName); Assert.Equal(DefaultUName, posix.UserName); Assert.Equal(DefaultDeviceMajor, posix.DeviceMajor); Assert.Equal(DefaultDeviceMinor, posix.DeviceMinor); if (entry is PaxTarEntry pax) { VerifyExtendedAttributeTimestamps(pax); } if (entry is GnuTarEntry gnu) { VerifyGnuTimestamps(gnu); } } }
private static bool IsExecutable(string fullPath) { Interop.Sys.FileStatus fileinfo; if (Interop.Sys.Stat(fullPath, out fileinfo) < 0) { return(false); } // Check if the path is a directory. if ((fileinfo.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { return(false); } const UnixFileMode AllExecute = UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute; UnixFileMode permissions = ((UnixFileMode)fileinfo.Mode) & AllExecute; // Avoid checking user/group when permission. if (permissions == AllExecute) { return(true); } else if (permissions == 0) { return(false); } uint euid = Interop.Sys.GetEUid(); if (euid == 0) { return(true); // We're root. } if (euid == fileinfo.Uid) { // We own the file. return((permissions & UnixFileMode.UserExecute) != 0); } bool groupCanExecute = (permissions & UnixFileMode.GroupExecute) != 0; bool otherCanExecute = (permissions & UnixFileMode.OtherExecute) != 0; // Avoid group check when group and other have same permissions. if (groupCanExecute == otherCanExecute) { return(groupCanExecute); } if (Interop.Sys.IsMemberOfGroup(fileinfo.Gid)) { return(groupCanExecute); } else { return(otherCanExecute); } }
public void ItGeneratesExecutableImage() { using TestDirectory testDirectory = TestDirectory.Create(); string sourceAppHostMock = PrepareAppHostMockFile(testDirectory); string destinationFilePath = Path.Combine(testDirectory.Path, "DestinationAppHost.exe.mock"); string appBinaryFilePath = "Test/App/Binary/Path.dll"; // strip executable permissions from this AppHost template binary File.SetUnixFileMode(sourceAppHostMock, UnixFileMode.UserRead | UnixFileMode.GroupRead | UnixFileMode.OtherRead); // -rwxr-xr-x const UnixFileMode expectedPermissions = UnixFileMode.UserRead | UnixFileMode.UserExecute | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherExecute; HostWriter.CreateAppHost( sourceAppHostMock, destinationFilePath, appBinaryFilePath, windowsGraphicalUserInterface: true); // assert that the generated app has executable permissions // despite different permissions on the template binary. File.GetUnixFileMode(destinationFilePath) .Should() .Be(expectedPermissions); }
public void CreateDoesntChangeExistingMode() { string path = GetRandomDirPath(); DirectoryInfo dir = Directory.CreateDirectory(path, AllAccess); UnixFileMode initialMode = dir.UnixFileMode; DirectoryInfo sameDir = Directory.CreateDirectory(path, UnixFileMode.UserRead); Assert.Equal(initialMode, sameDir.UnixFileMode); }
public void InvalidModeThrows(UnixFileMode mode, bool alreadyExists) { string path = GetRandomDirPath(); if (alreadyExists) { Directory.CreateDirectory(path); } Assert.Throws <ArgumentException>(() => Directory.CreateDirectory(path, mode)); }
public void CreateWithUnixFileMode(UnixFileMode mode) { string path = GetRandomDirPath(); DirectoryInfo dir = Directory.CreateDirectory(path, mode); // under Linux the created directory gets mode (mode & ~umask & 01777). // under OSX, it gets (mode & ~umask & 0777). UnixFileMode platformFilter = UnixFileMode.SetGroup | UnixFileMode.SetUser | (PlatformDetection.IsBsdLike ? UnixFileMode.StickyBit : UnixFileMode.None); UnixFileMode expectedMode = mode & ~GetUmask() & ~platformFilter; Assert.Equal(expectedMode, dir.UnixFileMode); }
public void MissingParentsHaveDefaultPermissions() { string parent = GetRandomDirPath(); string child = Path.Combine(parent, "child"); const UnixFileMode childMode = UnixFileMode.UserRead | UnixFileMode.UserExecute; DirectoryInfo childDir = Directory.CreateDirectory(child, childMode); Assert.Equal(childMode, childDir.UnixFileMode); UnixFileMode defaultPermissions = Directory.CreateDirectory(GetRandomDirPath()).UnixFileMode; Assert.Equal(defaultPermissions, File.GetUnixFileMode(parent)); }
public void SetThenGet(UnixFileMode mode) { if (GetModeNeedsReadableFile) { // Ensure the file remains readable. mode |= UnixFileMode.UserRead; } string path = CreateTestItem(); SetMode(path, mode); Assert.Equal(mode, GetMode(path)); }
public void CreateDoesntChangeExistingUnixFileMode(FileMode fileMode) { // Create file as writable for user only. const UnixFileMode mode = UnixFileMode.UserWrite; string filename = GetTestFilePath(); CreateFileStream(filename, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.None, preallocationSize: 0, mode).Dispose(); // Now open with AllAccess. using FileStream fs = CreateFileStream(filename, fileMode, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.None, preallocationSize: 0, AllAccess); UnixFileMode actualMode = File.GetUnixFileMode(filename); Assert.Equal(mode, actualMode); }
private static DirectoryInfo CreateDirectoryCore(string path, UnixFileMode unixCreateMode) { ArgumentException.ThrowIfNullOrEmpty(path); if ((unixCreateMode & ~FileSystem.ValidUnixFileModes) != 0) { throw new ArgumentException(SR.Arg_InvalidUnixFileMode, nameof(unixCreateMode)); } string fullPath = Path.GetFullPath(path); FileSystem.CreateDirectory(fullPath, unixCreateMode); return(new DirectoryInfo(path, fullPath, isNormalized: true)); }
public void CreateWithUnixFileMode(UnixFileMode mode) { string filename = GetTestFilePath(); FileStream fs = CreateFileStream(filename, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.None, preallocationSize: 0, mode); fs.Dispose(); UnixFileMode platformFilter = PlatformDetection.IsBsdLike ? (UnixFileMode.SetGroup | UnixFileMode.SetUser | UnixFileMode.StickyBit) : UnixFileMode.None; UnixFileMode expectedMode = mode & ~GetUmask() & ~platformFilter; UnixFileMode actualMode = File.GetUnixFileMode(filename); Assert.Equal(expectedMode, actualMode); }
private void SetUnixFileMode(SafeFileHandle?handle, string?path, UnixFileMode mode) { if ((mode & ~FileSystem.ValidUnixFileModes) != 0) { throw new ArgumentException(SR.Arg_InvalidUnixFileMode, nameof(UnixFileMode)); } // Linux does not support link permissions. // To have consistent cross-platform behavior we operate on the link target. int rv = handle is not null?Interop.Sys.FChMod(handle, (int)mode) : Interop.Sys.ChMod(path !, (int)mode); Interop.CheckIo(rv, path); InvalidateCaches(); }
public void UnixCreateModeThrowsForNonCreatingFileModes(FileMode fileMode, bool canSetUnixCreateMode) { const UnixFileMode unixMode = UnixFileMode.UserWrite; string filename = GetTestFilePath(); if (canSetUnixCreateMode) { CreateFileStream(filename, fileMode, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.None, preallocationSize: 0, unixMode).Dispose(); UnixFileMode actualMode = File.GetUnixFileMode(filename); Assert.Equal(unixMode, actualMode); } else { Assert.Throws <ArgumentException>(() => CreateFileStream(filename, fileMode, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.None, preallocationSize: 0, unixMode)); } }
protected static UnixFileMode GetUmask() { if (s_umask == (UnixFileMode)(-1)) { // The umask can't be retrieved without changing it. // We launch a child process to get its value. using Process px = Process.Start(new ProcessStartInfo { FileName = "/bin/sh", ArgumentList = { "-c", "umask" }, RedirectStandardOutput = true }); string stdout = px.StandardOutput.ReadToEnd().Trim(); s_umask = (UnixFileMode)Convert.ToInt32(stdout, 8); } return(s_umask); }
protected void VerifyPlatformSpecificMetadata(string filePath, TarEntry entry) { Interop.Sys.FileStatus status = default; status.Mode = default; status.Dev = default; Interop.CheckIo(Interop.Sys.LStat(filePath, out status)); Assert.Equal((int)status.Uid, entry.Uid); Assert.Equal((int)status.Gid, entry.Gid); if (entry is PosixTarEntry posix) { string gname = Interop.Sys.GetGroupName(status.Gid); string uname = Interop.Sys.GetUserNameFromPasswd(status.Uid); Assert.Equal(gname, posix.GroupName); Assert.Equal(uname, posix.UserName); if (entry.EntryType is not TarEntryType.BlockDevice and not TarEntryType.CharacterDevice) { Assert.Equal(DefaultDeviceMajor, posix.DeviceMajor); Assert.Equal(DefaultDeviceMinor, posix.DeviceMinor); } } if (entry.EntryType is not TarEntryType.Directory) { UnixFileMode expectedMode = (UnixFileMode)(status.Mode & 4095); // First 12 bits Assert.Equal(expectedMode, entry.Mode); Assert.True(entry.ModificationTime > DateTimeOffset.UnixEpoch); if (entry is PaxTarEntry pax) { VerifyExtendedAttributeTimestamps(pax); } if (entry is GnuTarEntry gnu) { VerifyGnuTimestamps(gnu); } } }
public void SetThenGet_SymbolicLink(UnixFileMode mode) { if (GetModeNeedsReadableFile) { // Ensure the file remains readable. mode |= UnixFileMode.UserRead; } string path = CreateTestItem(); string linkPath = GetTestFilePath(); File.CreateSymbolicLink(linkPath, path); SetMode(linkPath, mode); Assert.Equal(mode, GetMode(linkPath)); Assert.Equal(mode, GetMode(path)); }
public void Get() { string path = CreateTestItem(); UnixFileMode mode = GetMode(path); // Doesn't throw. Assert.NotEqual((UnixFileMode)(-1), mode); UnixFileMode required = UnixFileMode.UserRead | UnixFileMode.UserWrite; if (IsDirectory) { required |= UnixFileMode.UserExecute; } Assert.True((mode & required) == required); if (!PlatformDetection.IsBrowser) { // The umask should prevent this file from being writable by others. Assert.Equal(UnixFileMode.None, mode & UnixFileMode.OtherWrite); } }
/// <summary> /// Gets the file type from the mode /// </summary> /// <param name="mode">the file mode flags</param> /// <returns></returns> private static FileTypes GetFileType(UnixFileMode mode) { if ((mode & UnixFileMode.Socket) == UnixFileMode.Socket) { return(FileListingService.FileTypes.Socket); } if ((mode & UnixFileMode.SymbolicLink) == UnixFileMode.SymbolicLink) { return(FileListingService.FileTypes.Link); } if ((mode & UnixFileMode.Regular) == UnixFileMode.Regular) { return(FileListingService.FileTypes.File); } if ((mode & UnixFileMode.Block) == UnixFileMode.Block) { return(FileListingService.FileTypes.Block); } if ((mode & UnixFileMode.Directory) == UnixFileMode.Directory) { return(FileListingService.FileTypes.Directory); } if ((mode & UnixFileMode.Character) == UnixFileMode.Character) { return(FileListingService.FileTypes.Character); } if ((mode & UnixFileMode.FIFO) == UnixFileMode.FIFO) { return(FileListingService.FileTypes.FIFO); } return(FileListingService.FileTypes.Other); }
/// <summary> /// Creates a file on the file system with the entry?s contents and the specified name. /// The last write time of the file is set to the entry?s last write time. /// This method does allows overwriting of an existing file with the same name. /// </summary> /// /// <exception cref="UnauthorizedAccessException">The caller does not have the required permission.</exception> /// <exception cref="ArgumentException">destinationFileName is a zero-length string, contains only whitespace, /// or contains one or more invalid characters as defined by InvalidPathChars. -or- destinationFileName specifies a directory.</exception> /// <exception cref="ArgumentNullException">destinationFileName is null.</exception> /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception> /// <exception cref="DirectoryNotFoundException">The path specified in destinationFileName is invalid /// (for example, it is on an unmapped drive).</exception> /// <exception cref="IOException">An I/O error has occurred. /// -or- The entry is currently open for writing. /// -or- The entry has been deleted from the archive.</exception> /// <exception cref="NotSupportedException">destinationFileName is in an invalid format /// -or- The ZipArchive that this entry belongs to was opened in a write-only mode.</exception> /// <exception cref="InvalidDataException">The entry is missing from the archive or is corrupt and cannot be read /// -or- The entry has been compressed using a compression method that is not supported.</exception> /// <exception cref="ObjectDisposedException">The ZipArchive that this entry belongs to has been disposed.</exception> /// <param name="source">The zip archive entry to extract a file from.</param> /// <param name="destinationFileName">The name of the file that will hold the contents of the entry. /// The path is permitted to specify relative or absolute path information. /// Relative path information is interpreted as relative to the current working directory.</param> /// <param name="overwrite">True to indicate overwrite.</param> public static void ExtractToFile(this ZipArchiveEntry source, string destinationFileName, bool overwrite) { ArgumentNullException.ThrowIfNull(source); ArgumentNullException.ThrowIfNull(destinationFileName); FileStreamOptions fileStreamOptions = new() { Access = FileAccess.Write, Mode = overwrite ? FileMode.Create : FileMode.CreateNew, Share = FileShare.None, BufferSize = 0x1000 }; const UnixFileMode OwnershipPermissions = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute; // Restore Unix permissions. // For security, limit to ownership permissions, and respect umask (through UnixCreateMode). // We don't apply UnixFileMode.None because .zip files created on Windows and .zip files created // with previous versions of .NET don't include permissions. UnixFileMode mode = (UnixFileMode)(source.ExternalAttributes >> 16) & OwnershipPermissions; if (mode != UnixFileMode.None && !OperatingSystem.IsWindows()) { fileStreamOptions.UnixCreateMode = mode; } using (FileStream fs = new FileStream(destinationFileName, fileStreamOptions)) { using (Stream es = source.Open()) es.CopyTo(fs); } ArchivingUtils.AttemptSetLastWriteTime(destinationFileName, source.LastWriteTime); }
public void CreateTempSubdirectory(string prefix) { DirectoryInfo tmpDir = Directory.CreateTempSubdirectory(prefix); try { Assert.True(tmpDir.Exists); Assert.Equal(-1, tmpDir.FullName.IndexOfAny(Path.GetInvalidPathChars())); Assert.Empty(Directory.GetFileSystemEntries(tmpDir.FullName)); Assert.Equal(Path.TrimEndingDirectorySeparator(Path.GetTempPath()), tmpDir.Parent.FullName); if (!string.IsNullOrEmpty(prefix)) { Assert.StartsWith(prefix, tmpDir.Name); int expectedNameLength = prefix.Length + (OperatingSystem.IsWindows() ? 12 : 6); Assert.Equal(expectedNameLength, tmpDir.Name.Length); } if (!OperatingSystem.IsWindows()) { UnixFileMode userRWX = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute; Assert.Equal(userRWX, tmpDir.UnixFileMode); } // Ensure a file can be written to the directory string tempFile = Path.Combine(tmpDir.FullName, "newFile"); using (FileStream fs = File.Create(tempFile, bufferSize: 1024, FileOptions.DeleteOnClose)) { Assert.Equal(0, fs.Length); } } finally { tmpDir.Delete(recursive: true); } }
/// <summary> /// Checks the store directory has the correct permissions. /// </summary> /// <param name="path"> /// The path of the directory to check. /// </param> /// <param name="userId"> /// The current userId from GetEUid(). /// </param> private static void EnsureDirectoryPermissions(string path, uint userId) { Interop.Sys.FileStatus dirStat; if (Interop.Sys.Stat(path, out dirStat) != 0) { Interop.ErrorInfo error = Interop.Sys.GetLastErrorInfo(); throw new CryptographicException( SR.Cryptography_FileStatusError, new IOException(error.GetErrorMessage(), error.RawErrno)); } if (dirStat.Uid != userId) { throw new CryptographicException(SR.Format(SR.Cryptography_OwnerNotCurrentUser, path)); } const UnixFileMode UserReadWriteExecute = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute; UnixFileMode permissions = File.GetUnixFileMode(path); if ((permissions & UserReadWriteExecute) != UserReadWriteExecute) { throw new CryptographicException(SR.Format(SR.Cryptography_InvalidDirectoryPermissions, path)); } }
/// <summary> /// Opens a UNIX file. /// </summary> /// <param name="fileName">The filepath.</param> /// <param name="fileMode">The file access mode.</param> /// <returns>A opened file.</returns> public static IFile Open(string fileName, UnixFileMode fileMode) { return new UnixFile(fileName, fileMode); }
public static extern SafeUnixHandle Open(string path, uint flags, UnixFileMode mode);
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long preallocationSize, UnixFileMode unixFileMode) => new FileInfo(path).Open( new FileStreamOptions { Mode = mode, Access = access, Share = share, BufferSize = bufferSize, Options = options, PreallocationSize = preallocationSize, UnixCreateMode = unixFileMode });
public void VerifyIncludeBaseDirectory(bool includeBaseDirectory) { using TempDirectory source = new TempDirectory(); using TempDirectory destination = new TempDirectory(); UnixFileMode baseDirectoryMode = TestPermission1; SetUnixFileMode(source.Path, baseDirectoryMode); string fileName1 = "file1.txt"; string filePath1 = Path.Join(source.Path, fileName1); File.Create(filePath1).Dispose(); UnixFileMode filename1Mode = TestPermission2; SetUnixFileMode(filePath1, filename1Mode); string subDirectoryName = "dir/"; // The trailing separator is preserved in the TarEntry.Name string subDirectoryPath = Path.Join(source.Path, subDirectoryName); Directory.CreateDirectory(subDirectoryPath); UnixFileMode subDirectoryMode = TestPermission3; SetUnixFileMode(subDirectoryPath, subDirectoryMode); string fileName2 = "file2.txt"; string filePath2 = Path.Join(subDirectoryPath, fileName2); File.Create(filePath2).Dispose(); UnixFileMode filename2Mode = TestPermission4; SetUnixFileMode(filePath2, filename2Mode); string destinationArchiveFileName = Path.Join(destination.Path, "output.tar"); TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory); using FileStream fileStream = File.OpenRead(destinationArchiveFileName); using TarReader reader = new TarReader(fileStream); List <TarEntry> entries = new List <TarEntry>(); TarEntry entry; while ((entry = reader.GetNextEntry()) != null) { entries.Add(entry); } int expectedCount = 3 + (includeBaseDirectory ? 1 : 0); Assert.Equal(expectedCount, entries.Count); string prefix = includeBaseDirectory ? Path.GetFileName(source.Path) + '/' : string.Empty; if (includeBaseDirectory) { TarEntry baseEntry = entries.FirstOrDefault(x => x.EntryType == TarEntryType.Directory && x.Name == prefix); Assert.NotNull(baseEntry); AssertEntryModeFromFileSystemEquals(baseEntry, baseDirectoryMode); } TarEntry entry1 = entries.FirstOrDefault(x => x.EntryType == TarEntryType.RegularFile && x.Name == prefix + fileName1); Assert.NotNull(entry1); AssertEntryModeFromFileSystemEquals(entry1, filename1Mode); TarEntry directory = entries.FirstOrDefault(x => x.EntryType == TarEntryType.Directory && x.Name == prefix + subDirectoryName); Assert.NotNull(directory); AssertEntryModeFromFileSystemEquals(directory, subDirectoryMode); string actualFileName2 = subDirectoryName + fileName2; // Notice the trailing separator in subDirectoryName TarEntry entry2 = entries.FirstOrDefault(x => x.EntryType == TarEntryType.RegularFile && x.Name == prefix + actualFileName2); Assert.NotNull(entry2); AssertEntryModeFromFileSystemEquals(entry2, filename2Mode); }
private void AddCertToStore(ICertificatePal certPal) { // This may well be the first time that we've added something to this store. Directory.CreateDirectory(_storePath); uint userId = Interop.Sys.GetEUid(); EnsureDirectoryPermissions(_storePath, userId); OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string thumbprint = copy.Thumbprint; bool findOpenSlot; // The odds are low that we'd have a thumbprint collision, but check anyways. string?existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot); if (existingFilename != null) { if (!copy.HasPrivateKey) { return; } try { using (X509Certificate2 fromFile = new X509Certificate2(existingFilename)) { if (fromFile.HasPrivateKey) { // We have a private key, the file has a private key, we're done here. return; } } } catch (CryptographicException) { // We can't read this file anymore, but a moment ago it was this certificate, // so go ahead and overwrite it. } } const UnixFileMode UserReadWrite = UnixFileMode.UserRead | UnixFileMode.UserWrite; string destinationFilename; FileStreamOptions options = new() { Mode = FileMode.CreateNew, UnixCreateMode = UserReadWrite, Access = FileAccess.Write }; if (existingFilename != null) { destinationFilename = existingFilename; options.Mode = FileMode.Create; // Before we open the file for writing the certificate, // ensure it is only accessible to the owner. try { File.SetUnixFileMode(existingFilename, UserReadWrite); } catch (IOException) // Ignore errors. We verify permissions when we've opened the file. { } } else if (findOpenSlot) { destinationFilename = FindOpenSlot(thumbprint); } else { destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension); } using (FileStream stream = new FileStream(destinationFilename, options)) { // Verify the file can only be read/written to by the owner. UnixFileMode actualMode = File.GetUnixFileMode(stream.SafeFileHandle); if (actualMode != UserReadWrite) { throw new CryptographicException(SR.Format(SR.Cryptography_InvalidFilePermissions, stream.Name)); } byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12) !; stream.Write(pkcs12, 0, pkcs12.Length); } } }
/// <summary> /// Opens a UNIX file and returns the file descriptor. /// </summary> /// <param name="fileName">The filepath.</param> /// <param name="fileMode">The file access mode.</param> /// <returns>The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.</returns> public static int OpenFileDescriptor(string fileName, UnixFileMode fileMode) { var mode = unchecked ((int) fileMode); return open(fileName, mode); }
internal void SetUnixFileMode(SafeFileHandle handle, UnixFileMode mode) => SetUnixFileMode(handle, handle.Path, mode);
internal void SetUnixFileMode(string path, UnixFileMode mode) => SetUnixFileMode(handle: null, path, mode);
public static void SetUnixFileMode(SafeFileHandle fileHandle, UnixFileMode mode) => SetUnixFileModeCore(fileHandle, mode);
/// <summary> /// Gets the file type from the mode /// </summary> /// <param name="mode">the file mode flags</param> /// <returns></returns> private static FileTypes GetFileType(UnixFileMode mode) { if ((mode & UnixFileMode.Socket) == UnixFileMode.Socket) { return FileListingService.FileTypes.Socket; } if ((mode & UnixFileMode.SymbolicLink) == UnixFileMode.SymbolicLink) { return FileListingService.FileTypes.Link; } if ((mode & UnixFileMode.Regular) == UnixFileMode.Regular) { return FileListingService.FileTypes.File; } if ((mode & UnixFileMode.Block) == UnixFileMode.Block) { return FileListingService.FileTypes.Block; } if ((mode & UnixFileMode.Directory) == UnixFileMode.Directory) { return FileListingService.FileTypes.Directory; } if ((mode & UnixFileMode.Character) == UnixFileMode.Character) { return FileListingService.FileTypes.Character; } if ((mode & UnixFileMode.FIFO) == UnixFileMode.FIFO) { return FileListingService.FileTypes.FIFO; } return FileListingService.FileTypes.Other; }
/// <summary> /// Initializes a new instance of the <see cref="UnixFile"/> class. /// </summary> /// <param name="filename">A pathname for the file.</param> /// <param name="fileMode">The file access mode.</param> public UnixFile(string filename, UnixFileMode fileMode) :this(OpenFileDescriptor(filename, fileMode)) { this.filename = filename; }