diff --git a/Kerberos.NET/Cache/FileHandle.cs b/Kerberos.NET/Cache/FileHandle.cs index 4d4e471..061451e 100644 --- a/Kerberos.NET/Cache/FileHandle.cs +++ b/Kerberos.NET/Cache/FileHandle.cs @@ -5,7 +5,10 @@ using System; using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; using System.Threading; +using Microsoft.Win32.SafeHandles; namespace Kerberos.NET.Client { @@ -17,6 +20,7 @@ internal class FileHandle : IDisposable private readonly FileMode mode; private readonly FileAccess access; private readonly FileShare share; + private static readonly MethodInfo? SetUnixFileMode = TryGetSetUnixFileMode(); private static readonly TimeSpan LockWaitTimeout = TimeSpan.FromMilliseconds(5000); @@ -41,7 +45,21 @@ public FileHandle(string file, FileMode mode, FileAccess access, FileShare share public FileStream OpenStream() { - return File.Open(this.file, this.mode, this.access, this.share); + var fs = File.Open(this.file, this.mode, this.access, this.share); + // When we create file on Unix we should make sure only current user has access to it. + if (this.access == FileAccess.Write && SetUnixFileMode != null) + { + const int UserRead = 256; + const int UserWrite = 128; + + try + { + SetUnixFileMode.Invoke(null, new object[] { fs.SafeFileHandle, (int)(UserRead | UserWrite) }); + } + catch { }; + } + + return fs; } public IDisposable AcquireReadLock() => new FileLock(this.mutex); @@ -60,6 +78,24 @@ private static string GetObjectName(string file, string type) .Replace(Path.VolumeSeparatorChar, '_'); } + private static MethodInfo? TryGetSetUnixFileMode() + { + MethodInfo? mi = null; + + // SetUnixFileMode was introduced in .NET 7.0 and works only on Unix systems + // We ignore any reflection errors during attempt to load it. + if (!RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) + { + try + { + mi = typeof(File).GetMethod("SetUnixFileMode", new Type[] { typeof(SafeFileHandle), Type.GetType("System.IO.UnixFileMode") }); + } + catch { } + } + + return mi; + } + private class FileLock : IDisposable { private readonly Mutex mutex;