private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericTransportAgent] RoutingAgent - OnSubmittedMessage fired..."); _config.RoutingAgentConfig.OnSubmittedMessage.ToList().ForEach( x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } }); }
/// <summary> /// Invoked by Exchange when a message has been submitted. /// </summary> /// <param name="source">The source of this event.</param> /// <param name="args">Arguments for this event.</param> void SubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs args) { string sPath = @"C:\test\"; if (args.MailItem.Message.Attachments != null && args.MailItem.Message.Attachments.Count > 0) { var mailItem = args.MailItem; try { /// 获取收件人 foreach (var recipient in mailItem.Recipients) { string dirName = sPath + recipient.Address.LocalPart + '@' + recipient.Address.DomainPart; if (!Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } MoveFile(dirName + "\\", args.MailItem.Message.Attachments); } } catch (Exception ex) { } } }
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericExchangeTransportagent] [RoutingAgent] OnSubmittedMessage fired..."); var emailItem = new EmailItem(e.MailItem); _config.RoutingAgentConfig.OnSubmittedMessage.ToList().ForEach( x => { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } }); if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
void xdpdfRoutingAgent_OnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Stopwatch stopwatch = new Stopwatch(); String messageid = e.MailItem.Message.MessageId.Substring(1, e.MailItem.Message.MessageId.Length - 2); // Strip brackets from messageid Log log = Log.Instance; log.Do(messageid + ": starting process", 1); stopwatch.Start(); //Detect a PDF among attachments for (int i = e.MailItem.Message.Attachments.Count - 1; i >= 0; i--) { Attachment attachment = e.MailItem.Message.Attachments[i]; if (xdpdf.xdpdfSettings.Default.ScanAllAttachments == true || attachment.ContentType == "application/pdf" || attachment.FileName.Substring(attachment.FileName.Length - 3, 3).ToLower() == "pdf") { log.Do(messageid + ": processing attachment: \"" + attachment.FileName + "\"", 2); Stream attachreadstream = attachment.GetContentReadStream(); PDFTools tools = new PDFTools(messageid, e.MailItem.Message.Attachments[i].FileName, attachreadstream); if (tools.Detect() == true) { log.Do(messageid + ": attachment \"" + attachment.FileName + "\" is detected as a PDF", 2); if (tools.ScanPDF()) { String footerstring = "The PDF attachment " + attachment.FileName + " has been disarmed. "; footerstring += "If it no longer works, please forward the following information to your mail administrator:"; PDFTools.AddFooterToBody(messageid, e.MailItem.Message.Body, footerstring); footerstring = messageid + "::" + tools.AttachGuid; PDFTools.AddFooterToBody(messageid, e.MailItem.Message.Body, footerstring); Stream attachwritestream = attachment.GetContentWriteStream(); tools.DisarmedStream.WriteTo(attachwritestream); attachwritestream.Flush(); attachwritestream.Close(); } } else { log.Do(messageid + ": attachment \"" + attachment.FileName + "\" is not detected as a PDF", 2); } attachreadstream.Close(); } } stopwatch.Stop(); log.Do(messageid + ": finished - processing took " + stopwatch.Elapsed.Milliseconds + "ms", 1); Trace.Flush(); }
// <summary>Add an X-header to note the size of a message as it was // received from the Internet.</summary> private void SubmittedMessage( SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Debug.WriteLine(logPrefix + "Message submitted"); if (true) { Header sizeHeader = Header.Create(sizeHeaderName); // Note that MailItem.GetMimeReadStream().Length will re- // examine the MIME DOM with every access, which is expensive. // It is better to use MailItem.MimeStreamLength, which // evaluates the message once and then caches the size unless // the message is changed. sizeHeader.Value = e.MailItem.MimeStreamLength.ToString(); e.MailItem.Message.MimeDocument.RootPart.Headers.AppendChild(sizeHeader); } }
/// <summary> /// Invoked by Exchange when a message has been submitted. /// </summary> /// <param name="source">The source of this event.</param> /// <param name="args">Arguments for this event.</param> void SubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs args) { Debug.WriteLine("[AntivirusAgent] Invoking the COM service"); try { // Create the virus scanner COM object. Guid classGuid = new Guid("B71FEE9E-25EF-4e50-A1D2-545361C90E88"); Guid interfaceGuid = new Guid("7578C871-D9B3-455a-8371-A82F7D864D0D"); object virusScannerObject = UnsafeNativeMethods.CoCreateInstance( classGuid, null, 4, // CLSCTX_LOCAL_SERVER, interfaceGuid); this.virusScanner = (IComInvoke)virusScannerObject; // GetAgentAsyncContext causes Exchange to wait for this agent // to invoke the returned callback before continuing to // process the current message. this.agentAsyncContext = this.GetAgentAsyncContext(); this.mailItem = args.MailItem; // Invoke the virus scanner. this.virusScanner.BeginVirusScan((IComCallback)this); } catch (System.Runtime.InteropServices.COMException ex) { Debug.WriteLine("[AntivirusAgent] " + ex.ToString()); if (this.agentAsyncContext != null) { this.agentAsyncContext.Complete(); } } return; }
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericTransportAgent] RoutingAgent - OnSubmittedMessage fired..."); var emailItem = new EmailItem(e.MailItem); foreach (var x in Configuration.Config.RoutingAgentConfig.OnSubmittedMessage) { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } } if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
private void OnOnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs queuedMessageEventArgs) { lock (_fileLock) { AgentAsyncContext agentAsyncContext = null; try { var mailItem = queuedMessageEventArgs.MailItem; agentAsyncContext = GetAgentAsyncContext(); // check the sender whitelist if (_exchangeAttachmentFilterConfig.SendersWhitelist.Any( f => Regex.IsMatch(mailItem.FromAddress.ToString(), WildcardToRegex(f)))) { return; } // maybe we will need list of recipients on single line... var recipientList = new StringBuilder(); for (var i = 0; i < mailItem.Recipients.Count; i++) { recipientList.Append(i == 0 ? mailItem.Recipients[i].Address.ToString() : "; " + mailItem.Recipients[i].Address); } var removedAttachments = new List <Attachment>(); var strippedAttachments = new List <Attachment>(); var messageRejected = false; var messageLogStringBuilder = new SysLogBuilder(); var mailItemStatusText = $"[from: {mailItem.FromAddress}] [to: {recipientList}] [method: {mailItem.InboundDeliveryMethod}] [subject: {mailItem.Message.Subject}] [size: {mailItem.MimeStreamLength.ToString("N0")}]"; messageLogStringBuilder.Log(mailItemStatusText); if (mailItem.Message.Attachments.Count == 0 && _exchangeAttachmentFilterConfig.LogAccepted) { messageLogStringBuilder.LogPadded( "ACCEPTED: [reason: no attachments]"); } else { foreach (var attachment in mailItem.Message.Attachments) { // It would be great idea to process only attachments with size greater // than some threshold, 'cos infected files are always quite small (only few kB) // But I am not sure how to get the attachment size here, ... // if (any previous) attachment rejected the message then break the processing now if (messageRejected) { break; } AttachmentFilterStatus attachmentStatus = null; if (_exchangeAttachmentFilterConfig.DsnStripOriginalMessage) { // DSN has InboundDeliveryMethod equal to DeliveryMethod.File and FromAddress is equal to <> // and DSN's original message is included as message/rfc822 attachment if (mailItem.InboundDeliveryMethod == DeliveryMethod.File && mailItem.FromAddress.ToString() == "<>" && attachment.ContentType.ToLower().Equals("message/rfc822")) { attachmentStatus = new AttachmentFilterStatus(AttachmentFilterStatusEnum.StripAttachment, "DSN original message"); } } if (attachmentStatus == null) { // default file status (by extension) attachmentStatus = FilenameFilterStatus(attachment.FileName); // is it archive? if (_exchangeAttachmentFilterConfig.ScanArchives && IsArchive(attachment.FileName)) { var archiveStatus = ProcessArchiveStream(attachment.GetContentReadStream()); if (archiveStatus.Status > attachmentStatus.Status) { attachmentStatus = archiveStatus; } } // is it OpenXml document? if (_exchangeAttachmentFilterConfig.ScanOpenXmlDocuments && IsOpenXmlDocument(attachment.FileName)) { var openXmlDocumentStatus = ProcessOpenXmlDocumentStream(attachment.GetContentReadStream()); if (openXmlDocumentStatus.Status > attachmentStatus.Status) { attachmentStatus = openXmlDocumentStatus; } } } var attachmentStatusText = $"[file: {attachment.FileName}] [type: {attachment.AttachmentType}] [content type:{attachment.ContentType}] [reason: {attachmentStatus.Reason}]"; switch (attachmentStatus.Status) { case AttachmentFilterStatusEnum.Accept: if (_exchangeAttachmentFilterConfig.LogAccepted) { messageLogStringBuilder.LogPadded($"ACCEPTED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.RemoveAttachment: // just mark this attachment for removement, but do not touch attachments collection now // (we are in foreach loop and need to process them all) removedAttachments.Add(attachment); if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"REMOVED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.StripAttachment: // just mark this attachment for removement, but do not touch attachments collection now // (we are in foreach loop and need to process them all) strippedAttachments.Add(attachment); if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"STRIPPED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.RejectMessage: // reject whole message if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"REJECTED: {attachmentStatusText}"); } messageRejected = true; break; } } } if (messageLogStringBuilder.MessageCount > 1) { SysLog.Log(messageLogStringBuilder); } // reject the message? if (messageRejected) { // delete the source message and do nothing more (we do not send DSN)... source.Delete(); return; } // for every attachment we marked as being removed create new txt attachment with some info why it happened... foreach (var removedAttachment in removedAttachments) { // new attachment filename var newFileName = $"{_exchangeAttachmentFilterConfig.RemovedAttachmentPrefix}{removedAttachment.FileName}.txt"; // add new attachment to the message... var newAttachment = mailItem.Message.Attachments.Add(newFileName); // ...and write content into it (info message) var newAttachmentWriter = new StreamWriter(newAttachment.GetContentWriteStream()); newAttachmentWriter.WriteLine(removedAttachment.FileName); newAttachmentWriter.WriteLine(); newAttachmentWriter.WriteLine(_exchangeAttachmentFilterConfig.RemovedAttachmentNewContent); newAttachmentWriter.Flush(); newAttachmentWriter.Close(); } // finally remove all attachments marked for removal foreach (var removedAttachment in removedAttachments) { mailItem.Message.Attachments.Remove(removedAttachment); } // ...and stripped attachments, too foreach (var strippedAttachment in strippedAttachments) { mailItem.Message.Attachments.Remove(strippedAttachment); } } catch (IOException ex) { SysLog.Log("IOException: " + ex.Message); } catch (Exception ex) { SysLog.Log("Exception: " + ex.Message); } finally { agentAsyncContext?.Complete(); } } }
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericExchangeTransportagent] [RoutingAgent] OnSubmittedMessage fired..."); var emailItem = new EmailItem(e.MailItem); _config.RoutingAgentConfig.OnSubmittedMessage.ToList().ForEach( x => { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } }); if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
public void MySubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject; }