internal void SaveEnforcedResponse(EnforceResponse ef, string filepath)
		{
			using (FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write))
			{
				m_EnforcedResponseSerializer.WriteObject(fs, ef);
			}
		}
Example #2
0
		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;
 }
Example #5
0
		public UIEnforceResponse(EnforceResponse enforceResponse)
		{
			m_enforceResponse = enforceResponse;
		}
Example #6
0
		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;
		}
Example #7
0
		/// <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;
		}
Example #8
0
		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;
		}
Example #9
0
		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();
			}
		}
Example #10
0
		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;
		}
Example #11
0
		/// <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();
			}
		}
Example #14
0
		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.");
				}
			}
		}
Example #15
0
		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));
				}
			}
		}