internal void SaveEnforcedResponse(EnforceResponse ef, string filepath) { using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write)) { m_EnforcedResponseSerializer.WriteObject(fs, ef); } }
public void ExecuteEncryptionTestScript(string scriptName, bool shouldSucceed) { try { ContentEncryptionManager.ClearPasswordCache(); string scriptPath = Path.Combine(TestFileDirectory, shouldSucceed ? "succeed" : "fail", scriptName); var passwordInfo = ParsePasswordInfo(scriptPath); using (RequestCreator rc = new RequestCreator()) { // Create a request based on the script file using (Request request = rc.CreateRequest(scriptPath)) { // Check attachments read into request correctly Assert.IsTrue(CheckAttachments(scriptPath, request), "CheckAttachments failed after initial request creation, script:" + scriptPath); IContentEncryptionUi ui = new MockContentEncryptionUi(passwordInfo, DecryptResult.Ok, DecryptionErrorAction.Cancel); using (var app = new WsApplication(new MSOutlook.Application(), false)) { using (Workshare.PolicyMarshaller.MailAttachmentTransform mat = new MailAttachmentTransform(Interop.Options.OptionApi.GetInt("LevelOfProcessingEmbeddedMessages"), app)) using (ContentEncryptionManager manager = new ContentEncryptionManager(mat.ExpandMSG, mat.PackMSG)) { // Check decryption Assert.AreEqual(shouldSucceed, manager.DecryptRequestAttachments(request, ui), "DecryptRequestAttachments response incorrect, script:" + scriptPath); if (shouldSucceed)// No point proceeding if we were expecting failure { EnforceResponse spoofResponse = new EnforceResponse(); spoofResponse.ModifiedRequest = request; // Now ensure we can re-encrypt it bool cancelSend = true; Assert.IsTrue(manager.ReencryptResponseAttachments(spoofResponse, out cancelSend), "ReencryptResponseAttachments failed, script:" + scriptPath); Assert.IsFalse(cancelSend, "cancelSend true, should be false, script:" + scriptPath); Assert.IsTrue(CheckAttachments(scriptPath, request), "CheckAttachments failed after re-encryption, script:" + scriptPath); // Ensure the encryption went OK CheckFilesEncrypted(passwordInfo, manager, spoofResponse); } } } } } } catch (Exception ex) { Assert.Fail(string.Format("Caught exception while executing: {0}. Exception: {1}", Path.GetFileName(scriptName), ex.Message)); throw; } finally { // Occasionally seeing a COM error when re-running tests, suspect its down to the Request writer not having cleaned up fully. GC.Collect(); GC.WaitForPendingFinalizers(); } }
protected override EnforceResponse CallEnforcer(IProgressCallback callback) { EnforceResponse er = new EnforceResponse(); er.Properties = new CustomProperty[] { new CustomProperty("Error.Test", "This is a fake error to test the enforce error handling."), new CustomProperty("Error.Test", "Exception in fake enforce handler"), new CustomProperty("Error.Test", "Block") }; return er; }
protected override EnforceResponse CallEnforcer(IProgressCallback callback) { EnforceResponse er = new EnforceResponse(); if (!m_aborted) { er.Properties = new CustomProperty[] { new CustomProperty("ABORT", "true") }; m_aborted = true; AbortHit = true; } else { er.Properties = new CustomProperty[] { new CustomProperty("SUCCESS", "true") }; } return er; }
public UIEnforceResponse(EnforceResponse enforceResponse) { m_enforceResponse = enforceResponse; }
private EnforceResponse ProcessProtectSimpleResponse(object progressCallback) { IProgressCallback callback = null; try { lock (m_processingActions) { m_encryptionManager.AddZipActionEncryptor(m_response); int steps = CalculateSteps(); callback = new TransparentActionProgressCallback((IPolicyClientProgressDialog) progressCallback, steps); m_enforcerResponse = CallEnforcer(callback); ResponseAnalyser.CollectAndSendEvents(m_response, ResponseAnalyser.EventType.Action); // We need to expand any archives created by the Zip Action, so that the // contained documents are correctly referenced by the IFile representation of the zip. bool cancelSend; m_encryptionManager.AssociateZipActionArchiveWithContent(m_enforcerResponse, m_response, out cancelSend); if (!cancelSend) { m_encryptionManager.ReencryptResponseAttachments(m_enforcerResponse, out cancelSend); } if (cancelSend) { m_policyClientDialog.AbortActions = true; return m_enforcerResponse; } m_uiEnforcerResponse = ResponseAdapter.UIEnforceResponseFromEnforceResponse(m_enforcerResponse); if (m_uiEnforcerResponse.ContainsAbort) { m_policyClientDialog.AbortActions = true; } } } finally { IDisposable disp = callback as IDisposable; if (disp != null) { disp.Dispose(); } } return m_enforcerResponse; }
/// <summary> /// Handles an exception thrown during enforcement. Creates a new EnforceResponse containing the exception details /// </summary> private EnforceResponse HandleException(Exception ex, Request request, string exceptionHandling) { Logger.LogError("Request manager detected exception in enforcement"); Logger.LogError(ex); EnforceResponse original = new EnforceResponse(); List<CustomProperty> properties = new List<CustomProperty>(); properties.Add(new CustomProperty("Error.Message", ex.Message)); properties.Add(new CustomProperty("Error.Stack", ex.StackTrace)); properties.Add(new CustomProperty("Error.Result", exceptionHandling)); if (exceptionHandling == "Abort") { properties.Add(new CustomProperty("ABORT", "true")); } original.Properties = properties.ToArray(); original.ModifiedRequest = request; StringBuilder sb = new StringBuilder(Resources.CRITICAL_EXCEPTION); sb.Append(' '); sb.Append(Resources.CONTACT_SYSTEM_ADMIN); m_errors.Add(sb.ToString()); m_exceptions.Add(ex); return original; }
private EnforceResponse responseDialog_ProcessResponseActions(object sender, ProcessResponseActionsArgs e) { //if (m_mailItem != null) //{ // m_mailItem.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olSave); //} IProgressCallback callback = null; try { lock (m_processingActions) { m_encryptionManager.AddZipActionEncryptor(m_response); int steps = CalculateSteps(); if (m_uiResponse.ProcessTransparently()) { if (ShowProgress) { callback = new TransparentActionProgressCallback(m_uiManager, steps); } } else { callback = new PolicyActionProgressCallback(m_uiManager, steps); } m_enforcerResponse = CallEnforcer(callback); ResponseAnalyser.CollectAndSendEvents(m_response, ResponseAnalyser.EventType.Action); // We need to expand any archives created by the Zip Action, so that the // contained documents are correctly referenced by the IFile representation of the zip. bool cancelSend; m_encryptionManager.AssociateZipActionArchiveWithContent(m_enforcerResponse, m_response, out cancelSend); if (!cancelSend) { m_encryptionManager.ReencryptResponseAttachments(m_enforcerResponse, out cancelSend); } if (cancelSend) { m_policyClientDialog.AbortActions = true; return m_enforcerResponse; } m_uiEnforcerResponse = ResponseAdapter.UIEnforceResponseFromEnforceResponse(m_enforcerResponse); if (m_uiEnforcerResponse.ContainsAbort) { m_policyClientDialog.AbortActions = true; } } } finally { IDisposable disp = callback as IDisposable; if (disp != null) { disp.Dispose(); } } return m_enforcerResponse; }
public EnforceResponse Enforce(Request request, Response response) { Logger.LogDebug("CONTENT ENFORCER: Enforce()"); if (null == request) throw new System.ArgumentNullException("request"); if (null == response) throw new System.ArgumentNullException("response"); bool isAppCacheNeeded = ResponseNeedsApplicationCache(response); List<IDisposable> disposeList = new List<IDisposable>(); try { IContainer virtualRoot; IPolicyResponseObject pro = ResponseAdaptor.GetPRO(response, request, out virtualRoot); disposeList.Add(pro as IDisposable); disposeList.Add(virtualRoot); ActionExecuter executer = new ActionExecuter(m_operationCallback); if (isAppCacheNeeded) { CacheOfficeApps(response); } IUniversalRequestObject uro = executer.ExecuteActions(pro, ref virtualRoot); disposeList.Add(uro as IDisposable); EnforceResponse enforcedResponse = new EnforceResponse(); enforcedResponse.Properties = new CustomProperty[0]; enforcedResponse.ModifiedRequest = RequestAdaptor.GetRequest(uro); return enforcedResponse; } ///TODO: resolve the fault v error code debate later. essentially need a test system to simulate /// the different scenarios. Note that the exception handling is part of the service agreement /// as opposed to the general Exception catch case below. catch (PolicyActionException actionException) { return HandleException(actionException, request, actionException.ExceptionHandling); } catch (Exception ex) { Logger.LogError("Content Enforcer General Failure"); Logger.LogError(ex); return HandleException(ex, request, ActionExceptionHandling.Prompt); } finally { //For now, just shut down cached applications at the end of a call. if (isAppCacheNeeded) { Logger.LogDebug("CONTENT ENFORCER: Closing MS Office Apps"); OfficeApplicationCache.Instance.ShutDown(); } Logger.LogDebug("CONTENT ENFORCER: Disposing URO's"); foreach (IDisposable disp in disposeList) { if (disp != null) { disp.Dispose(); } } disposeList.Clear(); } }
private static EnforceResponse HandleException(Exception ex, Request request, ActionExceptionHandling exceptionHandling) { Logger.LogError("Content Enforcer detected exception in enforcement"); Logger.LogError(ex); EnforceResponse original = new EnforceResponse(); List<CustomProperty> properties = new List<CustomProperty>(); WriteErrorProperties(ex, properties); properties.Add(new CustomProperty(ErrorResultKey, exceptionHandling.ToString())); if (exceptionHandling == ActionExceptionHandling.Abort) { properties.Add(new CustomProperty("ABORT", "true")); } original.Properties = properties.ToArray(); original.ModifiedRequest = request; return original; }
/// <summary> /// /// </summary> /// <param name="enforceResponse"></param> /// <returns></returns> public static UIEnforceResponse UIEnforceResponseFromEnforceResponse(EnforceResponse enforceResponse) { UIEnforceResponse uiEnforceResponse = new UIEnforceResponse(enforceResponse); uiEnforceResponse.Initialize(); return uiEnforceResponse; }
// The Zip Action will create zips, but it wont associate the zip IFile // with it's contents. This method will make those associations. public void AssociateZipActionArchiveWithContent(EnforceResponse enforcerResponse, Response response, out bool cancelSend) { if (enforcerResponse == null || enforcerResponse.ModifiedRequest == null || enforcerResponse.ModifiedRequest.Attachments == null) { cancelSend = false; return; } string containerFileName = string.Empty; try { // Make sure the zips are expanded. foreach (Attachment attachment in enforcerResponse.ModifiedRequest.Attachments) { if (attachment == null || attachment.File == null || attachment.File.FileType != FileType.ZIP) { Logger.LogDebug("Item was not a zip."); continue; } containerFileName = attachment.FileName; Logger.LogDebug("Container file name: " + containerFileName); // The zip file (created by the Zip Action) and it's document should be in the same folder. string folder = Path.GetDirectoryName(containerFileName); // See if the zip is encrypted, and if it is then get it's password. IContentEncryption contentEncryption = GetAssociatedEncryptionObject(attachment); string password; if (contentEncryption == null || string.IsNullOrEmpty(contentEncryption.OpenPassword)) { password = string.Empty; Logger.LogDebug("Container did not have a password."); } else { password = contentEncryption.OpenPassword; Logger.LogDebug("Container had a password."); } // Expand the zip and associate it to the document. // The zip is already effectively expanded on disk, so we need to update its IFile representation to reflect this. attachment.File.AssociateContainerWithExistingFiles(password, (string fileName, out string contentId, out string filePath) => GetExistingFileContentId(response, folder, fileName, out contentId, out filePath)); } cancelSend = false; return; } catch (FileNotFoundException ex) { Logger.LogError(ex.Message); } catch (KeyNotFoundException ex) { Logger.LogError(ex.Message); } LastErrorText = string.Format("Unable to associate existing files with container [{0}]", containerFileName); cancelSend = true; }
/// <summary> /// Helper method. Reencrypts any attachments in a processed request /// </summary> /// <returns> /// Returns true if all attachments were successfully re-encrypted. /// Returns false if the re-encryption of any attachment failed (TODO: AP: Maybe throw exception/return list containing names of failed attachments) /// </returns> public bool ReencryptResponseAttachments(EnforceResponse response, out bool cancelSend) { try { cancelSend = false; if (response == null || response.ModifiedRequest == null || response.ModifiedRequest.Attachments == null) { return true; } return ReencryptAttachments(response.ModifiedRequest.Attachments, out cancelSend); } finally { OfficeApplicationCache.Instance.ShutDown(); } }
public void TestAssociateZipActionArchiveWithContent(string docFileName, string zipFileName, string password) { // Use function currying to keep the password. Func<FileType, string, string, string, ContentItem> CreateContentItem = (ft, fp, ci, pi) => CreateZipActionContentItem(password, ft, fp, ci, pi); // A message with null parent ID, because it's the top-most element. const string emailBodyId = "1"; const string emailBodyName = "message subject/body"; ContentItem emailContentItem = CreateContentItem(FileType.Email, emailBodyName, emailBodyId, null); var emailAttachment = new Attachment(emailBodyName, emailBodyName, FileType.Email.ToString(), emailBodyId, emailBodyId, true); // A zip with parent being email const string zipId = "2"; string zipPath = Path.Combine(TestFileDirectory, zipFileName); ContentItem zipContentItem = CreateContentItem(FileType.ZIP, zipPath, zipId, emailBodyId); var zipAttachment = new Attachment(zipPath, zipPath, FileType.ZIP.ToString(), zipId, zipId, true); zipAttachment.File = new FcsFile(zipPath, Path.GetFileName(zipPath), zipId); // A doc with parent being zip. const string docId = "3"; string docPath = Path.Combine(TestFileDirectory, docFileName); ContentItem docContentItem = CreateContentItem(FileType.WordDocument, docPath, docId, zipId); var docAttachment = new Attachment(docPath, docPath, FileType.WordDocument.ToString(), docId, docId, true); docAttachment.File = new FcsFile(docPath, Path.GetFileName(docPath), docId); using (ContentEncryptionManager manager = new ContentEncryptionManager()) { if (!string.IsNullOrEmpty(password)) { manager.AddZipActionEncryptor(zipId, zipPath, password); } var contents = new ContentItem[] { emailContentItem, zipContentItem, docContentItem }; var response = new Response { Contents = contents }; var attachments = new Attachment[] { emailAttachment, zipAttachment, docAttachment }; var request = new Request { Attachments = attachments }; var enforce = new EnforceResponse { ModifiedRequest = request }; // The zip and it's document are not yet associated. Assert.AreEqual(0, zipAttachment.File.Files.Count, "The zip IFile should not contain any files before association."); Assert.IsFalse(zipAttachment.File.IsExpanded); if (!string.IsNullOrEmpty(password)) { Assert.AreEqual(null, zipAttachment.File.Password, "The zip IFile should not yet contain the password."); } bool cancelSend; manager.AssociateZipActionArchiveWithContent(enforce, response, out cancelSend); // The zip and it's document should now be associated. Assert.AreEqual(1, zipAttachment.File.Files.Count, "The zip IFile should contain 1 file after association."); Assert.IsTrue(zipAttachment.File.IsExpanded); if (!string.IsNullOrEmpty(password)) { Assert.AreEqual(password, zipAttachment.File.Password, "The zip IFile should now contain the correct password."); } } }
private static void CheckFilesEncrypted(Dictionary<string, MockContentEncryptionUi.PasswordInfo> passwordInfo, ContentEncryptionManager manager, EnforceResponse spoofResponse) { // Ensure all attachments are still encrypted/decrypted as defined in the encryptedDict foreach (var attachment in spoofResponse.ModifiedRequest.Attachments) { string relativePath = MockContentEncryptionUi.RemoveTempDirs(attachment.FileName); if (passwordInfo.ContainsKey(relativePath))// Its has an entry in the pwd dictionary so should be passworded { Assert.IsTrue(manager.IsEncrypted(attachment)); } } }