private void OnItemSend(IProxy mailItem, ref bool cancelEmailSend, ref ProcessResult processResult) { RequestManager requestManager = null; try { InitClientProgress(); PolicyContent.Request request = CreateRequest(mailItem); List<PolicyContent.Attachment> attachmentsNotProcessed = new List<PolicyContent.Attachment>(); // Remove the msg top level attachments from the request. We need to add them back after processing before updating the Notes proxy. // We do this because msg files are being lost in processing (ActionExecuter.RecreateAttachments)but since they are not supported // file types in Notes we can remove them from the attachment collection to be processed and add them back later after the call to // ProcessRequest. This does not affect msg files in zip containers and those are not lost. attachmentsNotProcessed.AddRange(ExtractAttachmentsOfTypeEmail(request)); bool bInternal = true; foreach (PolicyContent.RoutingItem rItem in request.Destination.Items) { foreach (PolicyContent.CustomProperty cProperty in rItem.Properties) { if ((cProperty.Name.ToLower(CultureInfo.InvariantCulture) == "internal") && (cProperty.Value.ToLower(CultureInfo.InvariantCulture) == "false")) { bInternal = false; break; } } if (!bInternal) break; } requestManager = new RequestManager(request, new NotesUIManager()); requestManager.MailItem = mailItem; requestManager.IsLotusNotesMailClient = true; bool bApplyPolicy = true; if (bInternal) { bApplyPolicy = Interop.Options.OptionApi.GetBool("EmailApplyProtectPolicyInternally"); } else { bApplyPolicy = Interop.Options.OptionApi.GetBool("EmailApplyProtectPolicyExternally"); } if (!bApplyPolicy) { cancelEmailSend = false; } else { bool bDisplayProgress = DisplayProgressOnMailSend(request); if (OptionApi.GetBool("EnableProtectSimple")) { requestManager.ProtectSimpleProfiles = GetWorkshareProfiles(mailItem, request, true, false); processResult = requestManager.ProcessRequestForProtectSimple(bDisplayProgress, true); } else { processResult = requestManager.ProcessRequest(m_clientProgress, bDisplayProgress, IsDynamicDiscoveryEnabled(request)); } switch (processResult) { case ProcessResult.CANCELLED: { cancelEmailSend = true; break; } case ProcessResult.PROCESSED: { // If a zip does not contain any supported documents the IgnoreForWorkshareActions is set (Workshare.PolicyContent.Attachment.IgnoreForWorkshareActions) // by the encryption manager (ContentEncryptionManager.ZipNeedsProcessing). This was done to improve Protect support for large files. // If the ZipNeedsProcessing property is set the attachment is removed from the response (Workshare.Policy.Adaptors.RequestAdaptor.GetURO). // We need to extract ANY attachment that was marked as IgnoreForWorkshareAction from the Request attachments and append them to the ModifiedRequest attachments // before updating the proxy else these attachments will be removed from the Notes mail item. attachmentsNotProcessed.AddRange(GetIgnoreForWorkshareActionAttachments(requestManager.Request)); // Add the msg top level attachments or attachments excluded from processing (IgnoreForWorkshareActions) to the processed collection before updating the proxy Workshare.PolicyContent.Attachment[] processedAttachments = requestManager.EnforceResponse.ModifiedRequest.Attachments; processedAttachments = AppendMissingAttachments(attachmentsNotProcessed.ToArray(), processedAttachments); DeleteProxyAttachments(mailItem, processedAttachments); // Not supported for Lotus Notes //if (SendLinkBase.ShouldExecuteSendLinkAction(requestManager.Response)) //{ // var notesSendLink = new NotesSendLink(); // cancelEmailSend = !notesSendLink.ExecuteSendLinkAction(mailItem, requestManager); // UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest); // break; //} UpdateProxyAttachments(mailItem, processedAttachments); UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest); cancelEmailSend = false; break; } case ProcessResult.ERRORS: case ProcessResult.EXCEPTION: { cancelEmailSend = !HandleErrors(requestManager.Errors); break; } //case ProcessResult.SERVER_PROFILE: //case ProcessResult.ERROR_OVERRIDE_USER_SELECTED_SEND: default: { // no violations or actions for this email - continue to send it. cancelEmailSend = false; break; } } } } catch (Exception ex) { cancelEmailSend = !ShouldContinueAfterException(ex); } finally { m_clientProgress.Complete(); m_clientProgress.Close(); } }
private void OnItemSend(MailItem mailItem, bool hasLargeAttachments, ref bool cancelEmailSend) { MailClientHookBase.PreCacheEventWaitForCompletion(); MailAttachmentTransform msgHandler = null; Request request = null; try { InitClientProgress(); request = CreateRequest(mailItem); request.HasLargeAttachments = hasLargeAttachments; //WriteOutRequest(request); msgHandler = new MailAttachmentTransform(GetMsgNestingLevelOption(), m_application, DisableAccessToDOMAttachments); List<Attachment> allAttachments = msgHandler.Flatten(request); if (msgHandler.AtLeastOneEmail) { request.Attachments = allAttachments.ToArray(); } m_uiManager.ParentHwnd = m_parentWnd; RequestManager requestManager = new RequestManager(request, m_uiManager, msgHandler.ExpandMSG, msgHandler.PackMSG); requestManager.TotalAttachmentSize = GetTotalAttachmentSize(mailItem); requestManager.IsSimpleMapi = IsSimpleMapi; requestManager.MailItem = mailItem; using (new WsActivationContext()) { bool bDisplayProgress = DisplayProgressOnMailSend(request); requestManager.SendAndProtect = SendAndProtect; requestManager.HasLargeAttachments = request.HasLargeAttachments; ProcessResult result; if (ProtectSimple) { bool isCorporateAccount = GetAccountType(mailItem) == MsOutlook.OlAccountType.olExchange; requestManager.ProtectSimpleProfiles = GetWorkshareProfiles(mailItem.Application, request, isCorporateAccount, msgHandler.AtLeastOneEmail); // If any of the attachment is a large attachment, then just show send-link profiles, remove everything else if (request.HasLargeAttachments) { int i = 0; var profiles = new WorkshareProfileCollection(); foreach (WorkshareProfile profile in requestManager.ProtectSimpleProfiles.Values) { if (profile.Name.Contains("Secure File Transfer")) { profiles.Add(i++, profile); } } requestManager.ProtectSimpleProfiles = profiles; } result = requestManager.ProcessRequestForProtectSimple(bDisplayProgress, isCorporateAccount); } else { result = requestManager.ProcessRequest(m_clientProgress, bDisplayProgress, IsDynamicDiscoveryEnabled(request)); } switch (result) { case ProcessResult.CANCELLED: cancelEmailSend = true; break; case ProcessResult.PROCESSED: cancelEmailSend = false; ////////////////////////////////////////////////////////////////////////////////////////// // JE - 21.01.2010 // This code block ensures that for simple attachments (i.e not containers - zip,msg) // we will only replace the attachment on the email if we have processed it. // Container atachments will currently always be replaced with rebuilt versions // that contain copies of the original files that may or may not have been processed. ////////////////////////////////////////////////////////////////////////////////////////// Attachment[] builtup = requestManager.EnforceResponse.ModifiedRequest.Attachments; if (requestManager.ReplaceAllAttachments()) { // This is used for the Cryptzone Secure Email Action // We can only support one Action that has this property and still function // in a reasonable fashion since we are allowing the Action to remove all // attachments and replace then with completely new ones. JE 19.10.2011 msgHandler.ReplaceAttachments(mailItem, builtup); } else { List<Attachment> processedbuiltup = requestManager.GetTopLevelProcessedAttachments(); // VE263 Consolidate all the attachments (processed and unprocessed), so that we can recreate the email and have all the attachments in their original order. // Otherwise modified attachments would be added to the end of the attachment list, ie no longer in the original order. builtup = BuildMsgAndProcessedAttachments(msgHandler, builtup, processedbuiltup); if (SendLinkBase.ShouldExecuteSendLinkAction(requestManager.Response)) { IsSendLink = ExecuteSendLinkAction(mailItem, builtup, requestManager); cancelEmailSend = !IsSendLink; } else { msgHandler.ReplaceProcessedAttachments(mailItem, builtup, requestManager.GetGroupedZipOptions()); } } if (!cancelEmailSend) { if (IsSendLink) { SendLinkUpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest); } else { UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest); } SetHeaderProcessingInfo(mailItem, requestManager.EnforceResponse.ModifiedRequest); SetProcessedByWorkshareProtect(mailItem); RemoveCustomProperties(mailItem); } break; //VE 4955 - Don't tag the message (XHeader). Protect Server should //process the message if Protect Client failed to process the message //and the user selected to send anyway. case ProcessResult.ERROR_OVERRIDE_USER_SELECTED_SEND: cancelEmailSend = false; break; // I presume that an Exception result is actually // handled by a catch block, but case added here // to make sure that we show an error if it isn't. case ProcessResult.ERRORS: case ProcessResult.EXCEPTION: cancelEmailSend = !HandleErrors(requestManager.Errors); break; default: //no violations or actions for this email - continue to send it. if (request.HasLargeAttachments) { // and no policy triggered (probably because they are all not-supported types) // then we need to replace the place-holder-files (for large attachments) with actual attachments msgHandler.ReplaceAttachments(mailItem, request.Attachments); } IsProtectDisabledForCurrentRouting = true; cancelEmailSend = false; SetHeaderProcessingInfo(mailItem, requestManager.Request); SetProcessedByWorkshareProtect(mailItem); RemoveCustomProperties(mailItem); break; } } } catch (Exception ex) { cancelEmailSend = !ShouldContinueAfterException(ex); } finally { if (!cancelEmailSend && request != null) { foreach (var att in request.Attachments) { ContentEncryptionManager.ClearPasswordCacheFor(att); } } if (m_clientProgress != null) { m_clientProgress.Complete(); m_clientProgress.Close(); } if (request != null) { request.Dispose(); request = null; } // Explicitly clear up Redemption in case any extended MAPI objects are left lying around IWSUtilities utils = Oif.CreateUtilities(); utils.Cleanup(); if (msgHandler != null) { msgHandler.Dispose(); } Interop.Logging.Logger.LogInfo("Shutting down application cache instance."); OfficeApplicationCache.Instance.ShutDown(); } }