Boolean FilterCallback(IntPtr sendDataPtr, IntPtr replyDataPtr) { Boolean ret = true; try { FilterAPI.MessageSendData messageSend = (FilterAPI.MessageSendData)Marshal.PtrToStructure(sendDataPtr, typeof(FilterAPI.MessageSendData)); if (FilterAPI.MESSAGE_SEND_VERIFICATION_NUMBER != messageSend.VerificationNumber) { MessageBoxHelper.PrepToCenterMessageBoxOnForm(this); MessageBox.Show("Received message corrupted.Please check if the MessageSendData structure is correct."); EventManager.WriteMessage(139, "FilterCallback", EventLevel.Error, "Received message corrupted.Please check if the MessageSendData structure is correct."); return(false); } EventManager.WriteMessage(149, "FilterCallback", EventLevel.Verbose, "Received message Id#" + messageSend.MessageId + " type:" + messageSend.MessageType + " CreateOptions:" + messageSend.CreateOptions.ToString("X") + " infoClass:" + messageSend.InfoClass + " fileName:" + messageSend.FileName); filterMessage.AddMessage(messageSend); FileProtectorUnitTest.FileIOEventHandler(messageSend); if (replyDataPtr.ToInt64() != 0) { FilterAPI.MessageReplyData messageReply = (FilterAPI.MessageReplyData)Marshal.PtrToStructure(replyDataPtr, typeof(FilterAPI.MessageReplyData)); //if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_TERMINATION_INFO) //{ // //the process termination callback, you can get the notification if you register the callback setting of the process filter. //} if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO) { //this is new process creation, you can block it here by returning the STATUS_ACCESS_DENIED, below is the process information FilterAPI.PROCESS_INFO processInfo = (FilterAPI.PROCESS_INFO)Marshal.PtrToStructure(sendDataPtr, typeof(FilterAPI.PROCESS_INFO)); messageReply.ReturnStatus = processInfo.Status; Marshal.StructureToPtr(messageReply, replyDataPtr, true); } else if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY) { //this is encryption filter rule with boolean config "REQUEST_ENCRYPT_KEY_AND_IV_FROM_SERVICE" enabled. //the filter driver request the IV and key to open or create the encrypted file. //if you want to deny the file open or creation, you set the value as below: //messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; EventManager.WriteMessage(200, "filtercallback", EventLevel.Verbose, messageSend.FileName + " FILTER_REQUEST_ENCRYPTION_IV_AND_KEY"); //Here we return the test iv and key to the filter driver, you need to replace with you own iv and key in your code. AESDataBuffer aesData = new AESDataBuffer(); aesData.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; aesData.IV = FilterAPI.DEFAULT_IV_TAG; aesData.IVLength = (uint)aesData.IV.Length; aesData.EncryptionKey = Utils.GetKeyByPassPhrase(DigitalRightControl.PassPhrase); aesData.EncryptionKeyLength = (uint)aesData.EncryptionKey.Length; byte[] aesDataArray = DigitalRightControl.ConvertAESDataToByteArray(aesData); messageReply.DataBufferLength = (uint)aesDataArray.Length; Array.Copy(aesDataArray, messageReply.DataBuffer, aesDataArray.Length); messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; } else if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_TAGDATA) { //this is encryption filter rule with boolean config "REQUEST_ENCRYPT_KEY_IV_AND_TAGDATA_FROM_SERVICE" enabled. //the filter driver request the IV and key to open or create the encrypted file. //if you want to deny the file open or creation, you set the value as below: //messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; if (messageSend.DataBufferLength > 0) { //this is the tag data which attached to the encrypted file . string tagDataStr = Encoding.Unicode.GetString(messageSend.DataBuffer); EventManager.WriteMessage(235, "filtercallback", EventLevel.Verbose, "EncryptedFile:" + messageSend.FileName + ",tagData:" + tagDataStr); } //Here we return the test iv ,key and tag data to the filter driver, you need to replace with you own iv and key in your code. AESDataBuffer aesData = new AESDataBuffer(); aesData.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; aesData.IV = FilterAPI.DEFAULT_IV_TAG; aesData.IVLength = (uint)aesData.IV.Length; aesData.EncryptionKey = Utils.GetKeyByPassPhrase(DigitalRightControl.PassPhrase); aesData.EncryptionKeyLength = (uint)aesData.EncryptionKey.Length; aesData.TagData = Encoding.Unicode.GetBytes("TagData:" + messageSend.FileName); aesData.TagDataLength = (uint)aesData.TagData.Length; byte[] aesDataArray = DigitalRightControl.ConvertAESDataToByteArray(aesData); messageReply.DataBufferLength = (uint)aesDataArray.Length; Array.Copy(aesDataArray, messageReply.DataBuffer, aesDataArray.Length); messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; } else { //this is for control filter driver when the pre-IO was registered. //here you can control the IO behaviour and modify the data. if (!FileProtectorUnitTest.UnitTestCallbackHandler(messageSend) || !FilterService.AuthorizeFileAccess(messageSend, ref messageReply)) { //to comple the PRE_IO messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_ACCESS_DENIED; messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; EventManager.WriteMessage(160, "FilterCallback", EventLevel.Error, "Return error for I/O request:" + ((FilterAPI.MessageType)messageSend.MessageType).ToString() + ",fileName:" + messageSend.FileName); } else { messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; } } Marshal.StructureToPtr(messageReply, replyDataPtr, true); } return(ret); } catch (Exception ex) { EventManager.WriteMessage(134, "FilterCallback", EventLevel.Error, "filter callback exception." + ex.Message); return(false); } }
static public bool GetFileAccessPermission(ref FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) { Boolean retVal = true; string fileName = messageSend.FileName; string lastError = string.Empty; string processName = string.Empty; string userName = string.Empty; string encryptKey = string.Empty; try { FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); FilterAPI.DecodeUserName(messageSend.Sid, out userName); //by default the tag data format is "accountName;ivStr" int tagDataLength = (int)messageSend.DataBufferLength; byte[] tagData = messageSend.DataBuffer; Array.Resize(ref tagData, tagDataLength); string tagStr = UnicodeEncoding.Unicode.GetString(tagData); int index = tagStr.IndexOf(";"); byte[] iv = tagData; if (index > 0) { string serverAccount = tagStr.Substring(0, index); string ivStr = tagStr.Substring(index + 1); iv = Utils.ConvertHexStrToByteArray(ivStr); } uint accessFlag = 0; retVal = IsFileAccessAuthorized(fileName, userName, processName, tagStr, ref encryptKey, ref accessFlag, ref lastError); if (retVal && !string.IsNullOrEmpty(encryptKey)) { byte[] keyArray = Utils.ConvertHexStrToByteArray(encryptKey); //write the iv and key to the reply data buffer with format FilterAPI.AESDataBuffer AESDataBuffer aesData = new AESDataBuffer(); if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY_AND_ACCESSFLAG) { aesData.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; } else { aesData.AccessFlags = FilterAPI.ALLOW_MAX_RIGHT_ACCESS; } aesData.IV = iv; aesData.IVLength = (uint)iv.Length; aesData.EncryptionKey = keyArray; aesData.EncryptionKeyLength = (uint)keyArray.Length; byte[] aesDataArray = DigitalRightControl.ConvertAESDataToByteArray(aesData); messageReply.DataBufferLength = (uint)aesDataArray.Length; Array.Copy(aesDataArray, messageReply.DataBuffer, aesDataArray.Length); messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; } } catch (Exception ex) { lastError = "GetFileAccessPermission exception." + ex.Message; EventManager.WriteMessage(340, "GetFileAccessPermission", EventLevel.Error, lastError); retVal = false; } if (!retVal) { byte[] errorBuffer = UnicodeEncoding.Unicode.GetBytes(lastError); Array.Copy(errorBuffer, messageSend.DataBuffer, errorBuffer.Length); messageSend.DataBufferLength = (uint)errorBuffer.Length; } return(retVal); }