public static void RemoveProcessFilterRule(ProcessFilterRule filterRule) { processFilterRuleSection.Instances.Remove(filterRule.ProcessNameFilterMask + filterRule.ProcessId); FilterAPI.RemoveProcessFilterEntry((uint)filterRule.ProcessNameFilterMask.Length * 2, filterRule.ProcessNameFilterMask); return; }
public static bool DecodeUserName(byte[] sid, out string userName) { bool ret = true; IntPtr sidStringPtr = IntPtr.Zero; string sidString = string.Empty; userName = string.Empty; try { lock (userNameTable) { //check the user name cache table if (userNameTable.ContainsKey(sid)) { userName = userNameTable[sid]; return(ret); } } IntPtr sidBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(sid, 0); if (FilterAPI.ConvertSidToStringSid(sidBuffer, out sidStringPtr)) { sidString = Marshal.PtrToStringAuto(sidStringPtr); SecurityIdentifier secIdentifier = new SecurityIdentifier(sidString); IdentityReference reference = secIdentifier.Translate(typeof(NTAccount)); userName = reference.Value; lock (userNameTable) { //check the user name cache table if (!userNameTable.ContainsKey(sid)) { userNameTable.Add(sid, userName); } } } else { string errorMessage = "Convert sid to sid string failed with error " + Marshal.GetLastWin32Error(); Console.WriteLine(errorMessage); } } catch (Exception ex) { Console.WriteLine(string.Format("Convert sid to user name got exception:{0}", ex.Message)); ret = false; } finally { if (sidStringPtr != null && sidStringPtr != IntPtr.Zero) { FilterAPI.LocalFree(sidStringPtr); } } return(ret); }
public static void Load() { filterRules.Clear(); try { filterRules = ConfigSetting.GetFilterRules(); filterConnectionThreads = ConfigSetting.Get("filterConnectionThreads", filterConnectionThreads); requestIORegistration = ConfigSetting.Get("requestIORegistration", requestIORegistration); displayEvents = ConfigSetting.Get("displayEvents", displayEvents); filterMessageLogName = ConfigSetting.Get("filterMessageLogName", filterMessageLogName); filterMessageLogFileSize = ConfigSetting.Get("filterMessageLogFileSize", filterMessageLogFileSize); maximumFilterMessages = ConfigSetting.Get("maximumFilterMessages", maximumFilterMessages); enableLogTransaction = ConfigSetting.Get("enableLogTransaction", enableLogTransaction); activatedLicense = ConfigSetting.Get("activatedLicense", activatedLicense); enableDefaultIVKey = ConfigSetting.Get("enableDefaultIVKey", enableDefaultIVKey); accountName = ConfigSetting.Get("accountName", accountName); outputMessageToConsole = ConfigSetting.Get("outputMessageToConsole", outputMessageToConsole); enableNotification = ConfigSetting.Get("enableNotification", enableNotification); eventLevel = (EventLevel)ConfigSetting.Get("eventLevel", (uint)eventLevel); masterPassword = ConfigSetting.Get("masterPassword", masterPassword); masterPassword = FilterAPI.AESEncryptDecryptStr(masterPassword, FilterAPI.EncryptType.Decryption); includedUsers = ConfigSetting.Get("includedUsers", includedUsers); excludedUsers = ConfigSetting.Get("excludedUsers", excludedUsers); } catch (Exception ex) { EventManager.WriteMessage(176, "LoadConfigSetting", CommonObjects.EventLevel.Error, "Load config file " + configFileName + " failed with error:" + ex.Message); } }
public static bool GetUniqueComputerId(ref string myComputerId, ref string lastError) { bool retVal = false; byte[] computerId = new byte[52]; GCHandle gcHandle = GCHandle.Alloc(computerId, GCHandleType.Pinned); try { uint computerIdLength = (uint)computerId.Length; IntPtr computerIdPtr = Marshal.UnsafeAddrOfPinnedArrayElement(computerId, 0); retVal = FilterAPI.GetUniqueComputerId(computerIdPtr, ref computerIdLength); if (!retVal || computerIdLength <= 0) { lastError = GetLastErrorMessage(); return(false); } Array.Resize(ref computerId, (int)computerIdLength); myComputerId = UnicodeEncoding.Unicode.GetString(computerId); return(true); } catch (Exception ex) { lastError = "Get computerId got exception,system return error:" + ex.Message; return(false); } finally { gcHandle.Free(); } }
public static bool ProcessEncryptedFile(string sourceFileName, string destFileName, out string lastError) { bool ret = false; lastError = string.Empty; try { ret = FilterAPI.ProcessEncryptedFile(sourceFileName, destFileName); if (!ret) { lastError = "ProcessEncryptedFile " + sourceFileName + ", destFileName " + destFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); return(ret); } File.SetAttributes(sourceFileName, FileAttributes.Normal); File.Delete(sourceFileName); } catch (Exception ex) { ret = false; lastError = "ProcessEncryptedFile " + sourceFileName + ", destFileName " + destFileName + " failed with error:" + ex.Message; } return(ret); }
public static void RemoveFilterRule(string includeFilterMask) { filterRuleSection.Instances.Remove(includeFilterMask); FilterAPI.RemoveFilterRule(includeFilterMask); return; }
ListViewItem GetFilterMessage(FilterAPI.MessageSendData messageSend, ref string[] filterMessages) { ListViewItem lvItem = new ListViewItem(); try { string userName = string.Empty; string processName = string.Empty; FilterAPI.DecodeUserName(messageSend.Sid, out userName); FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is the request comes from remote server userName += ",remote access from network."; } string[] listData = new string[listView_Message.Columns.Count]; int col = 0; listData[col++] = messageSend.MessageId.ToString(); listData[col++] = FormatDateTime(messageSend.TransactionTime); listData[col++] = userName; listData[col++] = processName + " (" + messageSend.ProcessId + ")"; listData[col++] = messageSend.ThreadId.ToString(); listData[col++] = FormatIOName(messageSend); listData[col++] = messageSend.FileObject.ToString("X"); listData[col++] = messageSend.FileName; listData[col++] = messageSend.FileSize.ToString(); listData[col++] = ((FileAttributes)messageSend.FileAttributes).ToString(); listData[col++] = FormatDateTime(messageSend.LastWriteTime); listData[col++] = FormatStatus(messageSend.Status); listData[col++] = FormatDescription(messageSend); filterMessages = listData; lvItem = new ListViewItem(listData, 0); if (messageSend.Status >= (uint)NtStatus.Status.Error) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Red; } else if (messageSend.Status > (uint)NtStatus.Status.Warning) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Yellow; } } catch (Exception ex) { EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); lvItem = null; } return(lvItem); }
public static T DecryptStrToObject <T>(string toDeserialize) { string decryptedStr = FilterAPI.AESEncryptDecryptStr(toDeserialize, FilterAPI.EncryptType.Decryption); XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringReader textReader = new StringReader(decryptedStr); return((T)xmlSerializer.Deserialize(textReader)); }
public static string EncryptObjectToStr <T>(T toSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringWriter textWriter = new StringWriter(); xmlSerializer.Serialize(textWriter, toSerialize); string encryptedText = FilterAPI.AESEncryptDecryptStr(textWriter.ToString(), FilterAPI.EncryptType.Encryption); return(encryptedText); }
/// <summary> /// Create an encrypted file with embedded digital right policy, distribute the encrypted file via internet, /// only the authorized users and processes can access the encrypted file. /// </summary> /// <param name="fileName"></param> /// <param name="passPhrase"></param> /// <param name="policy"></param> /// <param name="lastError"></param> /// <returns></returns> public static bool EncryptFileWithEmbeddedDRPolicy(string sourceFileName, string destFileName, byte[] encryptIV, byte[] encryptKey, DRPolicyData policy, out string lastError) { bool ret = false; FileStream fs = null; lastError = string.Empty; try { if (!File.Exists(sourceFileName)) { lastError = sourceFileName + " doesn't exist."; return(false); } FileInfo fileInfo = new FileInfo(sourceFileName); long fileSize = fileInfo.Length; byte[] AESBuffer = GetPolicyBuffer(fileSize, policy, encryptIV, encryptKey); //encrypt the file with encryption key and a iv key. ret = FilterAPI.AESEncryptFileToFile(sourceFileName, destFileName, (uint)encryptKey.Length, encryptKey, (uint)encryptIV.Length, encryptIV, false); if (!ret) { lastError = "Create encrypt file " + destFileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); return(ret); } fs = new FileStream(destFileName, FileMode.Append, FileAccess.Write, FileShare.Read); //append the DR policy to the encrypted file. fs.Write(AESBuffer, 0, AESBuffer.Length); //append the sizeof the DR policy fs.Write(BitConverter.GetBytes(AESBuffer.Length + 4), 0, 4); } catch (Exception ex) { ret = false; lastError = "Encrypt file " + sourceFileName + " failed with error:" + ex.Message; } finally { if (null != fs) { fs.Close(); } } return(ret); }
public bool AddFilterRule(string includeFileFilterMask, uint eventType, uint monitorIO, uint accessFlags) { bool retVal = false; try { FilterRule filterRule = new FilterRule(); filterRule.IncludeFileFilterMask = includeFileFilterMask; filterRule.EventType = eventType; filterRule.MonitorIO = monitorIO; filterRule.AccessFlag = accessFlags; filterRule.ExcludeProcessNames = "explorer.exe"; filterRule.Id = GlobalConfig.GetFilterRuleId(); if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) == (uint)FilterAPI.AccessFlag.ENABLE_HIDE_FILES_IN_DIRECTORY_BROWSING) { filterRule.HiddenFileFilterMasks = "*"; } if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) == (uint)FilterAPI.AccessFlag.ENABLE_FILE_ENCRYPTION_RULE) { filterRule.EncryptMethod = (int)FilterAPI.EncryptionMethod.ENCRYPT_FILE_WITH_SAME_KEY_AND_IV; filterRule.EncryptionPassPhrase = "easefilter"; } Console.WriteLine("Receive AddFilterRule command,includeFileFilterMask:" + includeFileFilterMask + ",eventType:(0x)" + eventType.ToString("x") + ",monitorIO:(0x)" + monitorIO.ToString("x") + ",accessFlags:(0x)" + accessFlags.ToString("x")); retVal = GlobalConfig.AddFilterRule(filterRule); if (!retVal) { FilterAPI.GetLastErrorMessage(); EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Error, "AddFilterRule " + filterRule.IncludeFileFilterMask + " failed,filter returned:" + FilterAPI.GetLastErrorMessage()); return(false); } GlobalConfig.SendConfigSettingsToFilter(); EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Verbose, "AddFilterRule " + filterRule.IncludeFileFilterMask + " succeeded."); } catch (Exception ex) { EventManager.WriteMessage(43, "AddFilterRule", EventLevel.Error, "AddFilterRule " + includeFileFilterMask + " failed,system reported:" + ex.Message); return(false); } return(true); }
public static bool EncryptFileAndEmbedExpireTime(string fileName, string passPhrase, DateTime expireTimeUtc, out string lastError) { bool ret = false; lastError = string.Empty; try { if (!File.Exists(fileName)) { lastError = fileName + " doesn't exist."; return(false); } byte[] encryptionKey = Utils.GetKeyByPassPhrase(passPhrase); byte[] iv = Utils.GetRandomIV(); ret = FilterAPI.AESEncryptFile(fileName, (uint)encryptionKey.Length, encryptionKey, (uint)iv.Length, iv, false); if (!ret) { lastError = "Encrypt file " + fileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); return(ret); } FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read); long fileSize = fs.Length; BinaryWriter bw = new BinaryWriter(fs); bw.Write(FilterAPI.MESSAGE_SEND_VERIFICATION_NUMBER); bw.Write(fileSize); bw.Write(iv); bw.Write(expireTimeUtc.ToFileTimeUtc()); fs.Close(); FileAttributes attributes = File.GetAttributes(fileName) | FileAttributes.ReadOnly; File.SetAttributes(fileName, attributes); } catch (Exception ex) { ret = false; lastError = "EncryptFileAndEmbedExpireTime " + fileName + " failed with error:" + ex.Message; } return(ret); }
/// <summary> /// To open encrypted file without the filter driver interception, read the raw data with the return file handle. /// The caller is reponsible to close the file handle. /// </summary> /// <param name="fileName"></param> /// <param name="fileHandle"></param> /// <param name="lastError"></param> /// <returns></returns> public static bool OpenRawEnCyptedFile(string fileName, out IntPtr fileHandle, out string lastError) { fileHandle = IntPtr.Zero; lastError = string.Empty; uint bypassFilterFileAttributes = FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_OPEN_NO_RECALL | FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_REPARSE_POINT; try { if (!CreateFileAPI(fileName, (uint)FileAccess.Read, (uint)FileShare.None, (uint)FileMode.Open, bypassFilterFileAttributes, ref fileHandle)) { lastError = FilterAPI.GetLastErrorMessage(); return(false); } } catch (Exception ex) { lastError = "OpenRawEnCyptedFile " + fileName + " got exception,system return error:" + ex.Message; return(false); } return(true); }
ListViewItem GetFilterMessage(FilterAPI.MessageSendData messageSend, ref string[] filterMessages) { ListViewItem lvItem = new ListViewItem(); try { string userName = string.Empty; string processName = string.Empty; FilterAPI.DecodeUserName(messageSend.Sid, out userName); FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is the request comes from remote server string remoteIp = string.Empty; if (messageSend.DataBufferLength > 0 && ((uint)FilterAPI.MessageType.POST_CREATE == messageSend.MessageType)) { byte[] buffer = new byte[messageSend.DataBufferLength]; Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); remoteIp = Encoding.Unicode.GetString(buffer); userName += ",RemoteIP:" + remoteIp; } else { userName += ",Accessed from remote computer."; } } string[] listData = new string[listView_Message.Columns.Count]; int col = 0; listData[col++] = messageSend.MessageId.ToString(); listData[col++] = FormatDateTime(messageSend.TransactionTime); listData[col++] = userName; listData[col++] = processName + " (" + messageSend.ProcessId + ")"; listData[col++] = messageSend.ThreadId.ToString(); listData[col++] = FormatIOName(messageSend); listData[col++] = messageSend.FileObject.ToString("X"); listData[col++] = messageSend.FileName; listData[col++] = messageSend.FileSize.ToString(); listData[col++] = ((FileAttributes)messageSend.FileAttributes).ToString(); listData[col++] = FormatDateTime(messageSend.LastWriteTime); listData[col++] = FormatStatus(messageSend.Status); listData[col++] = FormatDescription(messageSend); filterMessages = listData; lvItem = new ListViewItem(listData, 0); if (messageSend.Status >= (uint)NtStatus.Status.Error) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Red; } else if (messageSend.Status > (uint)NtStatus.Status.Warning) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Yellow; } } catch (Exception ex) { EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); lvItem = null; } return(lvItem); }
static public bool StartFilter(int threadCount, string registerKey, FilterDelegate filterCallback, DisconnectDelegate disconnectCallback, ref string lastError) { bool ret = true; try { if (IsDriverChanged() || !FilterAPI.IsDriverServiceRunning()) { FilterAPI.UnInstallDriver(); //wait for 3 seconds for the uninstallation completed. System.Threading.Thread.Sleep(3000); ret = FilterAPI.InstallDriver(); if (!ret) { lastError = "Installed driver failed with error:" + FilterAPI.GetLastErrorMessage(); return(false); } else { isFilterStarted = false; EventManager.WriteMessage(59, "InstallDriver", EventLevel.Information, "Install filter driver succeeded."); } } if (!isFilterStarted) { if (!SetRegistrationKey(registerKey)) { lastError = "Set registration key failed with error:" + GetLastErrorMessage(); return(false); } gchFilter = GCHandle.Alloc(filterCallback); IntPtr filterCallbackPtr = Marshal.GetFunctionPointerForDelegate(filterCallback); gchDisconnect = GCHandle.Alloc(disconnectCallback); IntPtr disconnectCallbackPtr = Marshal.GetFunctionPointerForDelegate(disconnectCallback); isFilterStarted = RegisterMessageCallback(threadCount, filterCallbackPtr, disconnectCallbackPtr); if (!isFilterStarted) { lastError = "RegisterMessageCallback failed with error:" + GetLastErrorMessage(); return(false); } ret = true; } } catch (Exception ex) { ret = false; lastError = "Start filter failed with error " + ex.Message; } finally { if (!ret) { lastError = lastError + " Make sure you run this application as administrator."; } } return(ret); }
/// <summary> /// Process the encrypted file's embedded access policy, remove embedded information, add AESTagData to encrypted file, /// Create a filter driver aware encrypted file. Then you can read the encrypted file transparently via filter driver encryption engine. /// </summary> /// <param name="fileName"></param> /// <param name="passPhrase"></param> /// <param name="lastError"></param> /// <returns></returns> public static bool ProcessSecureShareFile(string fileName, out string lastError) { bool ret = false; lastError = string.Empty; try { if (!File.Exists(fileName)) { lastError = fileName + " doesn't exist."; return(false); } if (!fileName.EndsWith(SECURE_SHARE_FILE_EXTENSION)) { lastError = fileName + " extension is not correct."; return(false); } FileAttributes attributes = File.GetAttributes(fileName); attributes = (~FileAttributes.ReadOnly) & attributes; File.SetAttributes(fileName, attributes); FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); long fileSize = fs.Length; //read the last 4 bytes data, it is the total size of the embedded data. fs.Position = fileSize - 4; BinaryReader br = new BinaryReader(fs); uint sizeOfAESData = br.ReadUInt32(); if (sizeOfAESData >= fileSize) { lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize; return(false); } fs.Position = fileSize - sizeOfAESData; //Read the embedded data byte[] AESBuffer = new byte[sizeOfAESData]; fs.Read(AESBuffer, 0, (int)sizeOfAESData); //decrypt the embedded data, since the last 4 bytes is not encrypted, after decryption,need to write the clear size back. FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null); //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back. MemoryStream ms = new MemoryStream(AESBuffer); ms.Position = 0; br = new BinaryReader(ms); uint verificationKey = br.ReadUInt32(); //verify if this is the valid embedded data. if (verificationKey != AES_VERIFICATION_KEY) { lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid."; return(false); } //write back the size of embedded data here. ms.Position = ms.Length - 4; BinaryWriter bw = new BinaryWriter(ms); bw.Write(sizeOfAESData); //Remove the embedded data, this is the original file size without the embedded information. fs.SetLength(fileSize - sizeOfAESData); fs.Close(); fs = null; string newFileName = fileName.Remove(fileName.Length - SECURE_SHARE_FILE_EXTENSION.Length); File.Move(fileName, newFileName); //add the DR data to the encrypted file as a tag data. ret = FilterAPI.EmbedDRPolicyDataToFile(newFileName, AESBuffer, out lastError); } catch (Exception ex) { ret = false; lastError = "ProcessSecureShareFile " + fileName + " failed with error:" + ex.Message; } return(ret); }
private static byte[] GetPolicyBuffer(long fileSize, DRPolicyData policy, byte[] iv, byte[] encryptionKey) { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(AES_VERIFICATION_KEY); bw.Write((uint)(policy.AESFlags)); bw.Write(iv.Length); bw.Write(iv); bw.Write(encryptionKey.Length); if (encryptionKey.Length < 32) { //the struture always keep 32 bytes for encryption key. Array.Resize(ref encryptionKey, 32); } bw.Write(encryptionKey); bw.Write(policy.CreationTime); bw.Write(policy.ExpireTime); bw.Write((uint)policy.AccessFlags); bw.Write(fileSize); bw.Write(policy.LengthOfIncludeProcessNames); //the first offset lenght = current position + 13*4 // sizeof(OffsetOfIncludeProcessNames) + sizeof(OffsetOfExcludeProcessNames) + sizeof(LengthOfExcludeProcessNames) // + sizeof(OffsetOfIncludeUserNames) + sizeof(LengthOfIncludeUserNames) + sizeof(OffsetOfExcludeUserNames) + sizeof(LengthOfExcludeUserNames) // + sizeof(OffsetOfAccountName) + sizeof(LengthOfAccountName) + sizeof(OffsetOfComputerIds) + sizeof(LengthOfComputerIds) // + sizeof(LengthOfUserPassword) + sizeof(OffsetOfUserPassword) policy.OffsetOfIncludeProcessNames = (uint)ms.Length + 13 * 4; bw.Write(policy.OffsetOfIncludeProcessNames); bw.Write(policy.LengthOfExcludeProcessNames); policy.OffsetOfExcludeProcessNames = policy.OffsetOfIncludeProcessNames + policy.LengthOfIncludeProcessNames; bw.Write(policy.OffsetOfExcludeProcessNames); bw.Write(policy.LengthOfIncludeUserNames); policy.OffsetOfIncludeUserNames = policy.OffsetOfExcludeProcessNames + policy.LengthOfExcludeProcessNames; bw.Write(policy.OffsetOfIncludeUserNames); bw.Write(policy.LengthOfExcludeUserNames); policy.OffsetOfExcludeUserNames = policy.OffsetOfIncludeUserNames + policy.LengthOfIncludeUserNames; bw.Write(policy.OffsetOfExcludeUserNames); bw.Write(policy.LengthOfAccountName); policy.OffsetOfAccountName = policy.OffsetOfExcludeUserNames + policy.LengthOfExcludeUserNames; bw.Write(policy.OffsetOfAccountName); bw.Write(policy.LengthOfComputerIds); policy.OffsetOfComputerIds = policy.OffsetOfAccountName + policy.LengthOfAccountName; bw.Write(policy.OffsetOfComputerIds); bw.Write(policy.LengthOfUserPassword); policy.OffsetOfUserPassword = policy.OffsetOfComputerIds + policy.LengthOfComputerIds; bw.Write(policy.OffsetOfUserPassword); byte[] strBuffer; if (policy.LengthOfIncludeProcessNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeProcessNames); bw.Write(strBuffer); } if (policy.LengthOfExcludeProcessNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeProcessNames); bw.Write(strBuffer); } if (policy.LengthOfIncludeUserNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeUserNames); bw.Write(strBuffer); } if (policy.LengthOfExcludeUserNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeUserNames); bw.Write(strBuffer); } if (policy.LengthOfAccountName > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName); bw.Write(strBuffer); } if (policy.LengthOfComputerIds > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds); bw.Write(strBuffer); } if (policy.LengthOfUserPassword > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword); bw.Write(strBuffer); } byte[] AESBuffer = ms.ToArray(); //encrypt the access policy except the sizeOfAESData; FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null); return(AESBuffer); }
public static void SendConfigSettingsToFilter() { try { if (!FilterAPI.IsFilterStarted) { EventManager.WriteMessage(479, "SetFilterType", CommonObjects.EventLevel.Error, "SendConfigSettingsToFilter failed, the filter driver is not loaded."); return; } FilterAPI.ResetConfigData(); FilterAPI.SetConnectionTimeout(connectionTimeOut); if (!FilterAPI.SetFilterType((uint)filterType)) { EventManager.WriteMessage(443, "SetFilterType", CommonObjects.EventLevel.Error, "SetFilterType " + filterType.ToString() + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(447, "SetFilterType", CommonObjects.EventLevel.Information, "SetFilterType " + filterType.ToString() + " succeeded."); } //if you want the filter driver to use the devault IV key, you need to set this setting: if (enableDefaultIVKey) { uint boolConfig = (uint)FilterAPI.BooleanConfig.ENABLE_DEFAULT_IV_TAG; FilterAPI.SetBooleanConfig(boolConfig); } foreach (FilterRule filterRule in filterRules.Values) { //add filter rule to filter driver here, the filter rule is unique with the include file filter mask. //you can't have the mutiple filter rules with the same include file filter mask,if there are the same //one exist, the new one with accessFlag will overwrite the old accessFlag. //for control filter, if isResident is true, the access control will be enabled in boot time. if (!FilterAPI.AddNewFilterRule((uint)filterRule.AccessFlag, filterRule.IncludeFileFilterMask, filterRule.IsResident)) { EventManager.WriteMessage(456, "SendFilterRule", CommonObjects.EventLevel.Error, "Send filter rule failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(460, "SendFilterRule", CommonObjects.EventLevel.Information, "Send filter rule:" + filterRule.IncludeFileFilterMask); } if (!FilterAPI.RegisterEventTypeToFilterRule(filterRule.IncludeFileFilterMask, (uint)filterRule.EventType)) { EventManager.WriteMessage(478, "SendFilterRule", CommonObjects.EventLevel.Error, "Register event type:" + (FilterAPI.EVENTTYPE)filterRule.EventType + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(482, "SendFilterRule", CommonObjects.EventLevel.Information, "Register event type:" + (FilterAPI.EVENTTYPE)filterRule.EventType + " succeed."); } if (!FilterAPI.RegisterMoinitorIOToFilterRule(filterRule.IncludeFileFilterMask, filterRule.MonitorIO)) { EventManager.WriteMessage(499, "SendFilterRule", CommonObjects.EventLevel.Error, "Register monitor IO:" + filterRule.MonitorIO + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(503, "SendFilterRule", CommonObjects.EventLevel.Information, "Register monitor IO:" + filterRule.MonitorIO + " succeed."); } if (!FilterAPI.RegisterControlIOToFilterRule(filterRule.IncludeFileFilterMask, filterRule.ControlIO)) { EventManager.WriteMessage(508, "SendFilterRule", CommonObjects.EventLevel.Error, "Register control IO:" + filterRule.ControlIO + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(512, "SendFilterRule", CommonObjects.EventLevel.Information, "Register control IO:" + filterRule.ControlIO + " succeed."); } //every filter rule can have multiple exclude file filter masks, you can exclude the files //which matches the exclude filter mask. string[] excludeFilterMasks = filterRule.ExcludeFileFilterMasks.Split(new char[] { ';' }); if (excludeFilterMasks.Length > 0) { foreach (string excludeFilterMask in excludeFilterMasks) { if (excludeFilterMask.Trim().Length > 0) { if (!FilterAPI.AddExcludeFileMaskToFilterRule(filterRule.IncludeFileFilterMask, excludeFilterMask.Trim())) { EventManager.WriteMessage(496, "AddExcludeFileMaskToFilterRule", CommonObjects.EventLevel.Error, "AddExcludeFileMaskToFilterRule " + excludeFilterMask + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(500, "AddExcludeFileMaskToFilterRule", CommonObjects.EventLevel.Information, "AddExcludeFileMaskToFilterRule " + excludeFilterMask + " succeeded."); } } } } byte[] encryptionKey = null; uint encryptionKeyLength = 0; //you can enable the encryption per filter rule, set the FILE_ENCRYPTION_RULE to accessFlag, and add encryption key to the filter rule too. if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.FILE_ENCRYPTION_RULE) > 0 && filterRule.EncryptionPassPhrase.Length > 0) { encryptionKey = Utils.GetKeyByPassPhrase(filterRule.EncryptionPassPhrase); encryptionKeyLength = (uint)encryptionKey.Length; if (!FilterAPI.AddEncryptionKeyToFilterRule(filterRule.IncludeFileFilterMask, encryptionKeyLength, encryptionKey)) { EventManager.WriteMessage(482, "AddEncryptionKeyToFilterRule", CommonObjects.EventLevel.Error, "AddEncryptionKeyToFilterRule " + filterRule.IncludeFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(482, "AddEncryptionKeyToFilterRule", CommonObjects.EventLevel.Information, "AddEncryptionKeyToFilterRule succeeded."); } } string[] includeProcessNames = filterRule.IncludeProcessNames.Split(new char[] { ';' }); if (includeProcessNames.Length > 0) { foreach (string includeProcessName in includeProcessNames) { if (includeProcessName.Trim().Length > 0) { if (!FilterAPI.AddIncludeProcessNameToFilterRule(filterRule.IncludeFileFilterMask, includeProcessName.Trim())) { EventManager.WriteMessage(536, "AddIncludeProcessNameToFilterRule", CommonObjects.EventLevel.Error, "AddIncludeProcessNameToFilterRule " + includeProcessName + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(540, "AddIncludeProcessNameToFilterRule", CommonObjects.EventLevel.Information, "AddIncludeProcessNameToFilterRule " + includeProcessName + " succeeded."); } } } } string[] excludeProcessNames = filterRule.ExcludeProcessNames.Split(new char[] { ';' }); if (excludeProcessNames.Length > 0) { foreach (string excludeProcessName in excludeProcessNames) { if (excludeProcessName.Trim().Length > 0) { if (!FilterAPI.AddExcludeProcessNameToFilterRule(filterRule.IncludeFileFilterMask, excludeProcessName.Trim())) { EventManager.WriteMessage(556, "AddExcludeProcessNameToFilterRule", CommonObjects.EventLevel.Error, "AddExcludeProcessNameToFilterRule " + excludeProcessName + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(560, "AddExcludeProcessNameToFilterRule", CommonObjects.EventLevel.Information, "AddExcludeProcessNameToFilterRule " + excludeProcessName + " succeeded."); } } } } //set include process list for this filter rule. string[] includePidListInFilterRule = filterRule.IncludeProcessIds.Split(new char[] { ';' }); if (includePidListInFilterRule.Length > 0) { foreach (string inPidstr in includePidListInFilterRule) { if (inPidstr.Trim().Length > 0) { uint inPid = uint.Parse(inPidstr.Trim()); if (!FilterAPI.AddIncludeProcessIdToFilterRule(filterRule.IncludeFileFilterMask, inPid)) { EventManager.WriteMessage(523, "AddIncludeProcessIdToFilterRule", CommonObjects.EventLevel.Error, "AddIncludeProcessIdToFilterRule " + filterRule.IncludeFileFilterMask + " PID:" + inPidstr + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(527, "AddIncludeProcessIdToFilterRule", CommonObjects.EventLevel.Information, "AddIncludeProcessIdToFilterRule " + filterRule.IncludeFileFilterMask + " PID:" + inPidstr + " succeeded."); } } } } //set exclude process list for this filter rule. string[] excludePidListInFilterRule = filterRule.ExcludeProcessIds.Split(new char[] { ';' }); if (excludePidListInFilterRule.Length > 0) { foreach (string exPidstr in excludePidListInFilterRule) { if (exPidstr.Trim().Length > 0) { uint exPid = uint.Parse(exPidstr.Trim()); if (!FilterAPI.AddExcludeProcessIdToFilterRule(filterRule.IncludeFileFilterMask, exPid)) { EventManager.WriteMessage(545, "AddExcludeProcessIdToFilterRule", CommonObjects.EventLevel.Error, "AddExcludeProcessIdToFilterRule " + filterRule.IncludeFileFilterMask + " PID:" + exPidstr + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(549, "AddExcludeProcessIdToFilterRule", CommonObjects.EventLevel.Information, "AddExcludeProcessIdToFilterRule " + filterRule.IncludeFileFilterMask + " PID:" + exPidstr + " succeeded."); } } } } string[] includeUserNames = filterRule.IncludeUserNames.Split(new char[] { ';' }); if (includeUserNames.Length > 0) { foreach (string includeUserName in includeUserNames) { if (includeUserName.Trim().Length > 0) { if (!FilterAPI.AddIncludeUserNameToFilterRule(filterRule.IncludeFileFilterMask, includeUserName.Trim())) { EventManager.WriteMessage(536, "AddIncludeUserNameToFilterRule", CommonObjects.EventLevel.Error, "AddIncludeUserNameToFilterRule " + includeUserName + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(540, "AddIncludeUserNameToFilterRule", CommonObjects.EventLevel.Information, "AddIncludeUserNameToFilterRule " + includeUserName + " succeeded."); } } } } string[] excludeUserNames = filterRule.ExcludeUserNames.Split(new char[] { ';' }); if (excludeUserNames.Length > 0) { foreach (string excludeUserName in excludeUserNames) { if (excludeUserName.Trim().Length > 0) { if (!FilterAPI.AddExcludeUserNameToFilterRule(filterRule.IncludeFileFilterMask, excludeUserName.Trim())) { EventManager.WriteMessage(556, "AddExcludeUserNameToFilterRule", CommonObjects.EventLevel.Error, "AddExcludeUserNameToFilterRule " + excludeUserName + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(560, "AddExcludeUserNameToFilterRule", CommonObjects.EventLevel.Information, "AddExcludeUserNameToFilterRule " + excludeUserName + " succeeded."); } } } } string[] processRights = filterRule.ProcessRights.Split(new char[] { ';' }); if (processRights.Length > 0) { foreach (string processRight in processRights) { if (processRight.Trim().Length > 0) { string processName = processRight.Substring(0, processRight.IndexOf(':')); uint accessFlags = uint.Parse(processRight.Substring(processRight.IndexOf(':') + 1)); if (!FilterAPI.AddProcessRightsToFilterRule(filterRule.IncludeFileFilterMask, processName.Trim(), accessFlags)) { EventManager.WriteMessage(725, "AddProcessRightsToFilterRule", CommonObjects.EventLevel.Error, "AddProcessRightsToFilterRule " + filterRule.IncludeFileFilterMask + ",processName:" + processName + ",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(729, "AddProcessRightsToFilterRule", CommonObjects.EventLevel.Information, "AddProcessRightsToFilterRule " + filterRule.IncludeFileFilterMask + ",processName:" + processName + ",accessFlags:" + accessFlags + " succeeded."); } } } } string[] userRights = filterRule.UserRights.Split(new char[] { ';' }); if (userRights.Length > 0) { foreach (string userRight in userRights) { if (userRight.Trim().Length > 0) { string userName = userRight.Substring(0, userRight.IndexOf(':')); uint accessFlags = uint.Parse(userRight.Substring(userRight.IndexOf(':') + 1)); if (!FilterAPI.AddUserRightsToFilterRule(filterRule.IncludeFileFilterMask, userName.Trim(), accessFlags)) { EventManager.WriteMessage(748, "AddUserRightsToFilterRule", CommonObjects.EventLevel.Error, "AddUserRightsToFilterRule " + filterRule.IncludeFileFilterMask + ",userName:"******",accessFlags:" + accessFlags + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(752, "AddUserRightsToFilterRule", CommonObjects.EventLevel.Information, "AddUserRightsToFilterRule " + filterRule.IncludeFileFilterMask + ",userName:"******",accessFlags:" + accessFlags + " succeeded."); } } } } //Hide the files which match the hidden file filter masks when the user browse the managed directory. string[] hiddenFileFilterMasks = filterRule.HiddenFileFilterMasks.Split(new char[] { ';' }); if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.HIDE_FILES_IN_DIRECTORY_BROWSING) > 0 && hiddenFileFilterMasks.Length > 0) { foreach (string hiddenFilterMask in hiddenFileFilterMasks) { if (hiddenFilterMask.Trim().Length > 0) { if (!FilterAPI.AddHiddenFileMaskToFilterRule(filterRule.IncludeFileFilterMask, hiddenFilterMask.Trim())) { EventManager.WriteMessage(567, "AddHiddenFileMaskToFilterRule", CommonObjects.EventLevel.Error, "AddHiddenFileMaskToFilterRule " + filterRule.IncludeFileFilterMask + " hiddenFilterMask:" + hiddenFilterMask + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(567, "AddHiddenFileMaskToFilterRule", CommonObjects.EventLevel.Information, "AddHiddenFileMaskToFilterRule " + filterRule.IncludeFileFilterMask + " hiddenFilterMask:" + hiddenFilterMask + " succeeded."); } } } } //reparse the file open to another file with the filter mask. //For example: //FilterMask = c:\test\*txt //ReparseFilterMask = d:\reparse\*doc //If you open file c:\test\MyTest.txt, it will reparse to the file d:\reparse\MyTest.doc. string reparseFileFilterMask = filterRule.ReparseFileFilterMasks; if ((filterRule.AccessFlag & (uint)FilterAPI.AccessFlag.REPARSE_FILE_OPEN) > 0 && reparseFileFilterMask.Trim().Length > 0) { if (!FilterAPI.AddReparseFileMaskToFilterRule(filterRule.IncludeFileFilterMask, reparseFileFilterMask.Trim())) { EventManager.WriteMessage(791, "AddReparseFileMaskToFilterRule", CommonObjects.EventLevel.Error, "AddReparseFileMaskToFilterRule " + filterRule.IncludeFileFilterMask + " reparseFileFilterMask:" + reparseFileFilterMask + " failed:" + FilterAPI.GetLastErrorMessage()); } else { EventManager.WriteMessage(791, "AddReparseFileMaskToFilterRule", CommonObjects.EventLevel.Information, "AddReparseFileMaskToFilterRule " + filterRule.IncludeFileFilterMask + " reparseFileFilterMask:" + reparseFileFilterMask + " succeeded."); } } } //below is the global setting. //if you send the include process Id to filter driver, then only the include processes can //apply to the filter rules, all other processes will be skipped. foreach (uint includedPid in includePidList) { FilterAPI.AddIncludedProcessId(includedPid); } //if the exclude process list is not empty, all process in this list will be skipped by filter driver. foreach (uint excludedPid in excludePidList) { uint currentPid = FilterAPI.GetCurrentProcessId(); FilterAPI.AddExcludedProcessId(currentPid); FilterAPI.AddExcludedProcessId(excludedPid); } FilterAPI.RegisterIoRequest(requestIORegistration); foreach (uint protectPid in protectPidList) { FilterAPI.AddProtectedProcessId(protectPid); } } catch (Exception ex) { EventManager.WriteMessage(502, "SendConfigSettingsToFilter", CommonObjects.EventLevel.Error, "Send config settings to filter failed with error " + ex.Message); } }
/// <summary> /// Process the encrypted file's embedded access policy, remove embedded information, add AESTagData to encrypted file, /// Create a filter driver aware encrypted file. Then you can read the encrypted file transparently via filter driver encryption engine. /// </summary> /// <param name="fileName"></param> /// <param name="passPhrase"></param> /// <param name="lastError"></param> /// <returns></returns> public static bool ConvertFileToFilterDriverAwareEncryptFile(string fileName, string passPhrase, out string lastError) { bool ret = false; lastError = string.Empty; try { if (!File.Exists(fileName)) { lastError = fileName + " doesn't exist."; return(false); } FileAttributes attributes = File.GetAttributes(fileName); attributes = (~FileAttributes.ReadOnly) & attributes; File.SetAttributes(fileName, attributes); FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); long fileSize = fs.Length; //read the last 4 bytes data, it is the total size of the embedded data. fs.Position = fileSize - 4; BinaryReader br = new BinaryReader(fs); uint sizeOfAESData = br.ReadUInt32(); if (sizeOfAESData >= fileSize) { lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize; return(false); } fs.Position = fileSize - sizeOfAESData; //Read the embedded data byte[] AESBuffer = new byte[sizeOfAESData]; fs.Read(AESBuffer, 0, (int)sizeOfAESData); //decrypt the embedded data, since the last 4 bytes is not encrypted, after decryption,need to write the clear size back. byte[] encryptionKey = Utils.GetKeyByPassPhrase(passPhrase); FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, encryptionKey, FilterAPI.DEFAULT_IV_TAG); //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back. MemoryStream ms = new MemoryStream(AESBuffer); ms.Position = 0; br = new BinaryReader(ms); uint verificationKey = br.ReadUInt32(); //verify if this is the valid embedded data. if (verificationKey != AES_VERIFICATION_KEY) { lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid."; return(false); } //write back the size of embedded data here. ms.Position = ms.Length - 4; BinaryWriter bw = new BinaryWriter(ms); bw.Write(sizeOfAESData); //Remove the embedded data, this is the original file size without the embedded information. fs.SetLength(fileSize - sizeOfAESData); fs.Close(); fs = null; //add the embedded data to the tag data of the encrypted file. ret = FilterAPI.AddAESData(fileName, AESBuffer, out lastError); } catch (Exception ex) { ret = false; lastError = "EncryptFileAndEmbedExpireTime " + fileName + " failed with error:" + ex.Message; } return(ret); }
public static void RegistryFilterUnitTest(RichTextBox richTextBox_TestResult) { string lastError = string.Empty; string userName = Environment.UserDomainName + "\\" + Environment.UserName; string testRegistryKey = "SYSTEM\\CurrentControlSet\\Services\\EaseFilter"; string testValueKey = "DisplayName"; //full registry access rights uint accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; ulong regCallbackClass = 0; bool testPassed = true; unitTestResult = richTextBox_TestResult; try { string message = "Registry Filter Driver Unit Test."; AppendUnitTestResult(message, Color.Black); // //registry access flag test,set full registry access rights for current process. // if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) { AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); return; } using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) { string valueName = (string)regkey.GetValue(testValueKey); AppendUnitTestResult("1.Test full registry access rights in accessFlag passed, return valueName:" + valueName, Color.Gray); } } catch (Exception ex) { AppendUnitTestResult("1.Test registry access flag failed with error:" + ex.Message, Color.Red); testPassed = false; } if (testPassed) { //disable registry open key right test accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG & (uint)(~FilterAPI.RegControlFlag.REG_ALLOW_OPEN_KEY); try { if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) { AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); return; } using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) { string valueName = (string)regkey.GetValue(testValueKey); AppendUnitTestResult("2.Test disable open registry key right in accessFlag failed, get valueName " + valueName + " succedded.", Color.Red); } } catch { AppendUnitTestResult("2.Test disable open registry key right in accessFlag passed.", Color.Green); } } //test query value key callback, we will receive the callback registry query value key. accessFlag = FilterAPI.MAX_REGITRY_ACCESS_FLAG; regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key; try { if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) { AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); return; } using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) { string valueName = (string)regkey.GetValue(testValueKey); Thread.Sleep(2000); if (postQueryValueKeyPassed) { AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback passed, return valueName:" + valueName, Color.Green); } else { AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed, didn't receive callback message.", Color.Red); } } } catch (Exception ex) { AppendUnitTestResult("3.Test registry query value key Reg_Post_Query_Value_Key callback failed:" + ex.Message, Color.Red); } //test registry access callback control, in callback function we will block the setting of the value name if it succeeds. regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_Key | (uint)FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx; try { if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) { AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); return; } using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) { regkey.CreateSubKey("newSubkey"); AppendUnitTestResult("4.Test block creating new registry sub key in callback failed, the new subkey was created in callback.", Color.Red); } } catch (Exception ex) { AppendUnitTestResult("4.Test block creating new registry sub key in callback passed." + ex.Message, Color.Green); } //test registry access callback control, in callback function we will replace our virutal value back to user if it succeeds. regCallbackClass = (uint)FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key; try { if (!FilterAPI.AddRegFilterEntryById(FilterAPI.GetCurrentProcessId(), accessFlag, regCallbackClass, false)) { AppendUnitTestResult("AddRegFilterEntryById failed:" + FilterAPI.GetLastErrorMessage(), Color.Red); return; } using (Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(testRegistryKey)) { object value = regkey.GetValue("value1"); AppendUnitTestResult("5.Test modify registry return data in callback passed, return value " + value + ",type:" + value.GetType().ToString(), Color.Green); } } catch (Exception ex) { AppendUnitTestResult("5.Test modify registry return data in callback failed: " + ex.Message, Color.Red); } }
public static bool IOAccessControl(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) { bool ret = true; try { messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; // //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture // // //if you don't want to change anything to this IO request, just let it pass through as below setting: //messageReply.FilterStatus = 0; //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.DataBufferLength = the return data buffer length. // messageReply.DataBuffer = the data you want to return. // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; uint dataLength = messageSend.DataBufferLength; byte[] data = messageSend.DataBuffer; //here is some IO information for your reference: if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is file access request comes from remote network server } //you can check the file create option with this data: //"DesiredAccess: messageSend.DesiredAccess //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); //"CreateOptions:"messageSend.CreateOptions //Here is the demo to copy file content before it was deleted.----------------------------------------------- bool isFileDeleting = false; if (messageSend.Status == (uint)NtStatus.Status.Success) { if (messageType == FilterAPI.MessageType.POST_CREATE) { if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) { isFileDeleting = true; } } else if (messageType == FilterAPI.MessageType.PRE_SET_INFORMATION) { if (infoClass == WinData.FileInfomationClass.FileDispositionInformation) { isFileDeleting = true; } } if (isFileDeleting) { IntPtr fileHandle = IntPtr.Zero; bool retVal = FilterAPI.GetFileHandleInFilter(messageSend.FileName, (uint)FileAccess.Read, ref fileHandle); if (retVal) { SafeFileHandle sHandle = new SafeFileHandle(fileHandle, true); FileStream fileStream = new FileStream(sHandle, FileAccess.Read); //copy your data here... fileStream.Close(); } } } //End ----------------------------------------------- switch (messageType) { case FilterAPI.MessageType.PRE_CREATE: { //here you reparse the file open to another new file name //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; break; } case FilterAPI.MessageType.PRE_CACHE_READ: case FilterAPI.MessageType.POST_CACHE_READ: case FilterAPI.MessageType.PRE_NOCACHE_READ: case FilterAPI.MessageType.POST_NOCACHE_READ: case FilterAPI.MessageType.PRE_PAGING_IO_READ: case FilterAPI.MessageType.POST_PAGING_IO_READ: case FilterAPI.MessageType.PRE_CACHE_WRITE: case FilterAPI.MessageType.POST_CACHE_WRITE: case FilterAPI.MessageType.PRE_NOCACHE_WRITE: case FilterAPI.MessageType.POST_NOCACHE_WRITE: case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: case FilterAPI.MessageType.POST_PAGING_IO_WRITE: { //byte[] returnData = //new data you want to modify the read/write data; //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; ////for pre IO,use this one //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; break; } case FilterAPI.MessageType.PRE_SET_INFORMATION: case FilterAPI.MessageType.POST_SET_INFORMATION: case FilterAPI.MessageType.PRE_QUERY_INFORMATION: case FilterAPI.MessageType.POST_QUERY_INFORMATION: { switch (infoClass) { case WinData.FileInfomationClass.FileRenameInformation: { if (FilterAPI.MessageType.PRE_SET_INFORMATION == messageType) { string blockFileName = @"c:\filterTest\blockRename.txt"; //test block rename to blockFileName, it needs to register PRE_SET_INFORMATION; if (string.Compare(messageSend.FileName, blockFileName, true) == 0) { EventManager.WriteMessage(179, "IOAccessControl", EventLevel.Warning, "Block rename for file:" + messageSend.FileName); ret = false; break; } } //you can block file rename as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileDispositionInformation: { //you can block file delete as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileEndOfFileInformation: { //change file size break; } case WinData.FileInfomationClass.FileBasicInformation: { //file basic information break; } case WinData.FileInfomationClass.FileStandardInformation: { //file standard information break; } case WinData.FileInfomationClass.FileNetworkOpenInformation: { //file network information break; } case WinData.FileInfomationClass.FileInternalInformation: { //file internal inofrmation break; } default: { break; } } break; } } } catch (Exception ex) { EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); } return(ret); }
/// <summary> /// Create an encrypted file with embedded access control policy, distribute the encrypted file via internet, /// only the authorized users and processes can access the encrypted file. /// </summary> /// <param name="fileName"></param> /// <param name="passPhrase"></param> /// <param name="policy"></param> /// <param name="lastError"></param> /// <returns></returns> public static bool EncryptFileWithEmbeddedPolicy(string fileName, string passPhrase, AESAccessPolicy policy, out string lastError) { bool ret = false; FileStream fs = null; lastError = string.Empty; try { if (!File.Exists(fileName)) { lastError = fileName + " doesn't exist."; return(false); } FileAttributes attributes = File.GetAttributes(fileName); attributes = (~FileAttributes.ReadOnly) & attributes; File.SetAttributes(fileName, attributes); byte[] encryptionKey = Utils.GetKeyByPassPhrase(passPhrase); byte[] iv = Utils.GetRandomIV(); //encrypt the file with encryption key and a random iv key. ret = FilterAPI.AESEncryptFile(fileName, (uint)encryptionKey.Length, encryptionKey, (uint)iv.Length, iv, false); if (!ret) { lastError = "Encrypt file " + fileName + " failed with error:" + FilterAPI.GetLastErrorMessage(); return(ret); } fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read); long fileSize = fs.Length; MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(AES_VERIFICATION_KEY); bw.Write(policy.AESFlags); bw.Write(iv.Length); bw.Write(iv); bw.Write(policy.ExpireTime); bw.Write(policy.AccessFlags); bw.Write(fileSize); bw.Write(policy.LengthOfIncludeProcessNames); policy.OffsetOfIncludeProcessNames = (uint)ms.Length + 7 * 4; bw.Write(policy.OffsetOfIncludeProcessNames); bw.Write(policy.LengthOfExcludeProcessNames); policy.OffsetOfExcludeProcessNames = policy.OffsetOfIncludeProcessNames + policy.LengthOfIncludeProcessNames; bw.Write(policy.OffsetOfExcludeProcessNames); bw.Write(policy.LengthOfIncludeUserNames); policy.OffsetOfIncludeUserNames = policy.OffsetOfExcludeProcessNames + policy.LengthOfExcludeProcessNames; bw.Write(policy.OffsetOfIncludeUserNames); bw.Write(policy.LengthOfExcludeUserNames); policy.OffsetOfExcludeUserNames = policy.OffsetOfIncludeUserNames + policy.LengthOfIncludeUserNames; bw.Write(policy.OffsetOfExcludeUserNames); byte[] strBuffer; if (policy.LengthOfIncludeProcessNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeProcessNames); bw.Write(strBuffer); } if (policy.LengthOfExcludeProcessNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeProcessNames); bw.Write(strBuffer); } if (policy.LengthOfIncludeUserNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeUserNames); bw.Write(strBuffer); } if (policy.LengthOfExcludeUserNames > 0) { strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeUserNames); bw.Write(strBuffer); } uint sizeOfAESData = (uint)ms.Length + 4; byte[] AESBuffer = ms.ToArray(); //encrypt the access policy except the sizeOfAESData; FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, encryptionKey, FilterAPI.DEFAULT_IV_TAG); //append the access policy to the encrypted file. fs.Write(AESBuffer, 0, AESBuffer.Length); fs.Write(BitConverter.GetBytes(sizeOfAESData), 0, 4); //set the encrypted file to readonly here. attributes = File.GetAttributes(fileName) | FileAttributes.ReadOnly; File.SetAttributes(fileName, attributes); } catch (Exception ex) { ret = false; lastError = "EncryptFileAndEmbedExpireTime " + fileName + " failed with error:" + ex.Message; } finally { if (null != fs) { fs.Close(); } } return(ret); }