public static void RemoveProcessFilterRule(ProcessFilterRule filterRule)
        {
            processFilterRuleSection.Instances.Remove(filterRule.ProcessNameFilterMask + filterRule.ProcessId);
            FilterAPI.RemoveProcessFilterEntry((uint)filterRule.ProcessNameFilterMask.Length * 2, filterRule.ProcessNameFilterMask);

            return;
        }
예제 #2
0
        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);
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }
예제 #8
0
        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));
        }
예제 #9
0
        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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        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);
            }
        }
예제 #19
0
        /// <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);
        }
예제 #20
0
        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);
            }
        }
예제 #21
0
        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);
        }
예제 #22
0
        /// <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);
        }