1 /* 2 KeePass Password Safe - The Open-Source Password Manager 3 Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 using System; 21 using System.Collections.Generic; 22 using System.Diagnostics; 23 using System.IO; 24 using System.Reflection; 25 using System.Text; 26 using System.Xml; 27 28 namespace KeePassLib.Native 29 { 30 internal sealed class SimpleStat 31 { 32 private readonly object m_oPermissions; 33 private readonly long m_nUserId; 34 private readonly long m_nGroupId; 35 SimpleStat(object oPermissions, long nUserId, long nGroupId)36 private SimpleStat(object oPermissions, long nUserId, long nGroupId) 37 { 38 if(oPermissions == null) throw new ArgumentNullException("oPermissions"); 39 40 m_oPermissions = oPermissions; 41 m_nUserId = nUserId; 42 m_nGroupId = nGroupId; 43 } 44 Get(string strFilePath)45 public static SimpleStat Get(string strFilePath) 46 { 47 try 48 { 49 Type tUfsi, tUfi; 50 object oUfi = GetUnixFileInfo(strFilePath, out tUfsi, out tUfi); 51 if(oUfi == null) return null; 52 53 PropertyInfo piPerm = tUfsi.GetProperty("FileAccessPermissions", 54 BindingFlags.Public | BindingFlags.Instance); 55 if(piPerm == null) { Debug.Assert(false); return null; } 56 Debug.Assert(piPerm.PropertyType.IsEnum); 57 58 PropertyInfo piUser = tUfsi.GetProperty("OwnerUserId", 59 BindingFlags.Public | BindingFlags.Instance); 60 if(piUser == null) { Debug.Assert(false); return null; } 61 Debug.Assert(piUser.PropertyType == typeof(long)); 62 63 PropertyInfo piGroup = tUfsi.GetProperty("OwnerGroupId", 64 BindingFlags.Public | BindingFlags.Instance); 65 if(piGroup == null) { Debug.Assert(false); return null; } 66 Debug.Assert(piGroup.PropertyType == typeof(long)); 67 68 return new SimpleStat(piPerm.GetValue(oUfi, null), 69 (long)piUser.GetValue(oUfi, null), 70 (long)piGroup.GetValue(oUfi, null)); 71 } 72 catch(Exception) { Debug.Assert(false); } 73 74 return null; 75 } 76 Set(string strFilePath, SimpleStat s)77 public static void Set(string strFilePath, SimpleStat s) 78 { 79 if(s == null) { Debug.Assert(false); return; } 80 81 try 82 { 83 Type tUfsi, tUfi; 84 object oUfi = GetUnixFileInfo(strFilePath, out tUfsi, out tUfi); 85 if(oUfi == null) return; 86 87 PropertyInfo piPerm = tUfsi.GetProperty("FileAccessPermissions", 88 BindingFlags.Public | BindingFlags.Instance); 89 if(piPerm == null) { Debug.Assert(false); return; } 90 91 piPerm.SetValue(oUfi, s.m_oPermissions, null); 92 93 MethodInfo miOwner = tUfsi.GetMethod("SetOwner", 94 new Type[] { typeof(long), typeof(long) }); 95 if(miOwner == null) { Debug.Assert(false); return; } 96 97 miOwner.Invoke(oUfi, new object[] { s.m_nUserId, s.m_nGroupId }); 98 } 99 catch(Exception) { Debug.Assert(false); } 100 } 101 GetTypes(out Type tUfsi, out Type tUfi)102 private static bool GetTypes(out Type tUfsi, out Type tUfi) 103 { 104 tUfsi = null; 105 tUfi = null; 106 107 try 108 { 109 if(!NativeLib.IsUnix()) return false; 110 111 string strVer = typeof(XmlNode).Assembly.GetName().Version.ToString(); 112 string strPosix = "Mono.Posix, Version=" + strVer; 113 Assembly asmPosix = Assembly.Load(strPosix); 114 if(asmPosix == null) { Debug.Assert(false); return false; } 115 116 tUfsi = asmPosix.GetType("Mono.Unix.UnixFileSystemInfo", false); 117 tUfi = asmPosix.GetType("Mono.Unix.UnixFileInfo", false); 118 119 bool b = ((tUfsi != null) && (tUfi != null)); 120 Debug.Assert(b); 121 return b; 122 } 123 catch(Exception) { Debug.Assert(false); } 124 125 return false; 126 } 127 GetUnixFileInfo(string strFilePath, Type tUfi)128 private static object GetUnixFileInfo(string strFilePath, Type tUfi) 129 { 130 if(string.IsNullOrEmpty(strFilePath)) { Debug.Assert(false); return null; } 131 132 try 133 { 134 if(!File.Exists(strFilePath)) { Debug.Assert(false); return null; } 135 136 return Activator.CreateInstance(tUfi, strFilePath); 137 } 138 catch(Exception) { Debug.Assert(false); } 139 140 return null; 141 } 142 GetUnixFileInfo(string strFilePath, out Type tUfsi, out Type tUfi)143 private static object GetUnixFileInfo(string strFilePath, 144 out Type tUfsi, out Type tUfi) 145 { 146 if(!GetTypes(out tUfsi, out tUfi)) return null; 147 return GetUnixFileInfo(strFilePath, tUfi); 148 } 149 } 150 } 151