55
66using System ;
77using System . IO ;
8+ using System . Reflection ;
9+ using System . Runtime . InteropServices ;
810using System . Threading ;
11+ using Microsoft . Win32 . SafeHandles ;
912
1013namespace Kerberos . NET . Client
1114{
@@ -17,6 +20,7 @@ internal class FileHandle : IDisposable
1720 private readonly FileMode mode ;
1821 private readonly FileAccess access ;
1922 private readonly FileShare share ;
23+ private static readonly MethodInfo ? SetUnixFileMode = TryGetSetUnixFileMode ( ) ;
2024
2125 private static readonly TimeSpan LockWaitTimeout = TimeSpan . FromMilliseconds ( 5000 ) ;
2226
@@ -41,7 +45,21 @@ public FileHandle(string file, FileMode mode, FileAccess access, FileShare share
4145
4246 public FileStream OpenStream ( )
4347 {
44- return File . Open ( this . file , this . mode , this . access , this . share ) ;
48+ var fs = File . Open ( this . file , this . mode , this . access , this . share ) ;
49+ // When we create file on Unix we should make sure only current user has access to it.
50+ if ( this . access == FileAccess . Write && SetUnixFileMode != null )
51+ {
52+ const int UserRead = 256 ;
53+ const int UserWrite = 128 ;
54+
55+ try
56+ {
57+ SetUnixFileMode . Invoke ( null , new object [ ] { fs . SafeFileHandle , ( int ) ( UserRead | UserWrite ) } ) ;
58+ }
59+ catch { } ;
60+ }
61+
62+ return fs ;
4563 }
4664
4765 public IDisposable AcquireReadLock ( ) => new FileLock ( this . mutex ) ;
@@ -60,6 +78,24 @@ private static string GetObjectName(string file, string type)
6078 . Replace ( Path . VolumeSeparatorChar , '_' ) ;
6179 }
6280
81+ private static MethodInfo ? TryGetSetUnixFileMode ( )
82+ {
83+ MethodInfo ? mi = null ;
84+
85+ // SetUnixFileMode was introduced in .NET 7.0 and works only on Unix systems
86+ // We ignore any reflection errors during attempt to load it.
87+ if ( ! RuntimeInformation . IsOSPlatform ( System . Runtime . InteropServices . OSPlatform . Windows ) )
88+ {
89+ try
90+ {
91+ mi = typeof ( File ) . GetMethod ( "SetUnixFileMode" , new Type [ ] { typeof ( SafeFileHandle ) , Type . GetType ( "System.IO.UnixFileMode" ) } ) ;
92+ }
93+ catch { }
94+ }
95+
96+ return mi ;
97+ }
98+
6399 private class FileLock : IDisposable
64100 {
65101 private readonly Mutex mutex ;
0 commit comments