private void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
        {
            string[] addrs;
            //hash code is not guaranteed to be unique. Add time to fix uniqueness
            string itemId = e.MailItem.GetHashCode().ToString() + e.MailItem.FromAddress.ToString();

            if (this.origToMapping.TryGetValue(itemId, out addrs))
            {
                this.origToMapping.Remove(itemId);
                if (this.databaseConnector != null)
                {
                    this.databaseConnector.LogCatch(addrs[0], addrs[1], e.MailItem.Message.Subject, e.MailItem.Message.MessageId);
                }

                //Add / update orig to header
                if (CatchAllFactory.AppSettings.AddOrigToHeader)
                {
                    MimeDocument mdMimeDoc    = e.MailItem.Message.MimeDocument;
                    HeaderList   hlHeaderlist = mdMimeDoc.RootPart.Headers;
                    Header       origToHeader = hlHeaderlist.FindFirst("X-OrigTo");

                    if (origToHeader == null)
                    {
                        MimeNode   lhLasterHeader = hlHeaderlist.LastChild;
                        TextHeader nhNewHeader    = new TextHeader("X-OrigTo", addrs[0]);
                        hlHeaderlist.InsertBefore(nhNewHeader, lhLasterHeader);
                    }
                    else
                    {
                        origToHeader.Value += ", " + addrs[0];
                    }
                }
            }
        }
Esempio n. 2
0
        private void EndOfDataEventHandler(ReceiveMessageEventSource source, EndOfDataEventArgs args)
        {
            if (!DeliveryThrottling.Instance.CheckAndTrackThrottleConcurrentMessageSizeLimit(args.SmtpSession.SessionId, args.MailItem.Recipients.Count))
            {
                MSExchangeStoreDriver.DeliveryRetry.Increment();
                source.RejectMessage(AckReason.MaxConcurrentMessageSizeLimitExceeded);
                return;
            }
            string internetMessageId = args.MailItem.InternetMessageId;

            if (string.IsNullOrEmpty(internetMessageId))
            {
                DeliveryThrottlingAgent.Diag.TraceWarning(0, (long)this.GetHashCode(), "MessageId header is missing. Poison handling is disabled");
                return;
            }
            int crashCount = 0;

            if (DeliveryConfiguration.Instance.PoisonHandler.VerifyPoisonMessage(internetMessageId, out crashCount))
            {
                DeliveryThrottlingAgent.Diag.TraceError <string>(0, (long)this.GetHashCode(), "Poison message identified. Message ID: {0}", internetMessageId);
                source.RejectMessage(AckReason.InboundPoisonMessage(crashCount));
                return;
            }
            PoisonHandler <DeliveryPoisonContext> .Context = new DeliveryPoisonContext(internetMessageId);
        }
 private void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
 {
     Logger.Debug("[GenericTransportAgent] SmtpReceiveAgent - OnEndOfData fired...");
     foreach (var x in Configuration.Config.SmtpReceiveAgentConfig.OnEndOfData)
     {
         try
         {
             x.Execute(new EmailItem(e.MailItem));
         }
         catch (Exception ex)
         {
             Logger.Error(ex, @"Error executing ""OnEndOfData""");
         }
     }
 }
        /// <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 EndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs 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());
                this.agentAsyncContext.Complete();
            }

            return;
        }
 void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
 {
     Logger.Debug("[GenericTransportAgent] SmtpReceiveAgent - OnEndOfData fired...");
     _config.SmtpReceiveAgentConfig.OnEndOfData.ToList().ForEach(x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error executing ""OnEndOfData"""); } });
 }
Esempio n. 6
0
        private void OnEndOfDataHandler(
            ReceiveMessageEventSource source,
            EndOfDataEventArgs e)
        {
            string bodyAsText = "";
            StreamReader reader = new StreamReader(e.MailItem.Message.Body.GetContentReadStream(), Microsoft.Exchange.Data.Globalization.Charset.GetEncoding(e.MailItem.Message.Body.CharsetName), true);
            bodyAsText = reader.ReadToEnd();
            reader.Close();

            if ( this.ShouldBlockMessage(bodyAsText, e.MailItem.Message.Subject) ) {
                source.RejectMessage(
                    this.GetRejectResponse());
            }
        }
        /// <summary>
        /// Handles processing the message once the end of the DATA SMTP stream is sent.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="eodArgs"></param>
        public void OnEndOfDataHandler(ReceiveEventSource source, EndOfDataEventArgs eodArgs)
        {
            Byte[]            newlineNeedle      = Encoding.ASCII.GetBytes("\n");
            Byte[]            scoreNeedle        = Encoding.ASCII.GetBytes("X-Spam-Score: ");
            Byte[]            discardFlag        = Encoding.ASCII.GetBytes("X-Spam-Discard: YES\n");
            Byte[]            recievedNeedle     = Encoding.ASCII.GetBytes("Received: ");
            Byte[]            indentedLineNeedle = Encoding.ASCII.GetBytes(" ");
            Nullable <Double> score = null;

            this.logger.debug("OnEndOfDataHandler Called");

            // Wrap everything in a Try. This makes sure that even if something fails the message still passes through
            try
            {
                this.logger.info("OnEndOfDataHandler Info: FROM=" + eodArgs.MailItem.FromAddress.ToString() + ", REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString());

                // Check to make sure SpamAssassin exists at the path it's supposed to
                if (!System.IO.File.Exists(this.settings.SpamassassinPath))
                {
                    this.logger.fatal("Spamassassin does not exist at path: '" + this.settings.SpamassassinPath + "'. Bypassing.");
                    this.logger.flush();
                    return;
                }

                // Check to see if this is an internal message
                if (!eodArgs.SmtpSession.IsExternalConnection)
                {
                    foreach (EnvelopeRecipient recipient in eodArgs.MailItem.Recipients)
                    {
                        if (recipient.Address.LocalPart.IndexOf("HealthMailbox") == 0)
                        {
                            this.logger.info("Health Mailbox found in recipients. Bypassing.");
                            this.logger.flush();
                        }
                    }
                    this.logger.info("Internal Connection Found. Bypassing.");
                    this.logger.flush();
                }

                // Is the message too big?
                if (eodArgs.MailItem.MimeStreamLength > this.settings.MaxMessageSize)
                {
                    this.logger.warning("Message is too large. Increase MaxMessageSize to scan larger messages. MAXSIZE=" + this.settings.MaxMessageSize.ToString() + ", MESSAGESIZE=" + eodArgs.MailItem.MimeStreamLength.ToString());
                    this.logger.flush();
                }

                // Get the message stream
                Stream      message          = eodArgs.MailItem.GetMimeReadStream();
                List <Byte> messageBytes     = new List <Byte>(ReadFully(message));
                byte[]      messageByteArray = messageBytes.ToArray();
                message.Close();
                this.logger.debug("Message Stream Retrieved. BYTES=" + messageByteArray.Length.ToString());

                // Skip the top number of recieved lines
                int linestart      = 0;
                int lineend        = 0;
                int linestartmatch = 0;
                for (int i = 0; i < this.settings.SkipRecieved; i++)
                {
                    this.logger.debug("Skipping #" + i.ToString() + " Recieved line");
                    // Find the first instance of the Recieved header
                    linestart = ByteSearch.Locate(messageByteArray, recievedNeedle, 0);
                    // Loop until we find a line that doesn't start with a space.
                    do
                    {
                        lineend = ByteSearch.Locate(messageByteArray, newlineNeedle, linestart);
                        this.logger.debug("Located Line End: " + lineend.ToString());
                        linestartmatch = ByteSearch.Locate(messageByteArray, indentedLineNeedle, lineend);
                        this.logger.debug("Located LineStartMatch:" + linestartmatch.ToString());
                        messageBytes.RemoveRange(linestart, lineend - linestart + 1);
                        messageByteArray = messageBytes.ToArray();
                    } while (linestartmatch == lineend + 1);

                    this.logger.debug("Finished Skipping #" + i.ToString());
                }

                // Run spamassassin while piping stdin/stdout
                this.logger.debug("Starting SpamAssassin Process. PATH='" + this.settings.SpamassassinPath + "', ARGS='" + this.settings.SpamassassinArgs + "'");
                Process spamassassin = new Process();
                spamassassin.StartInfo.UseShellExecute        = false;
                spamassassin.StartInfo.FileName               = this.settings.SpamassassinPath;
                spamassassin.StartInfo.WorkingDirectory       = Path.GetDirectoryName(spamassassin.StartInfo.FileName);
                spamassassin.StartInfo.Arguments              = ("-s " + this.settings.MaxMessageSize + " " + this.settings.SpamassassinArgs).Trim();
                spamassassin.StartInfo.RedirectStandardInput  = true;
                spamassassin.StartInfo.RedirectStandardOutput = true;
                spamassassin.StartInfo.RedirectStandardError  = true;
                spamassassin.Start();
                this.logger.debug("Started SpamAssassin Process. PID='" + spamassassin.Id.ToString() + "'");

                // Copy the message into stdio using a byte for byte copy
                this.logger.debug("Copying message to Spamassassin. BYTES=" + messageByteArray.Length.ToString());
                spamassassin.StandardInput.BaseStream.Write(messageByteArray, 0, messageByteArray.Length);
                spamassassin.StandardInput.BaseStream.Flush();
                spamassassin.StandardInput.BaseStream.Close();

                // Read the entire output buffer, put it into a list for easy manipulation
                List <Byte> outBytes = new List <Byte>(ReadFully(spamassassin.StandardOutput.BaseStream));
                this.logger.debug("Read STDOUT from spamassassin. BYTES=" + outBytes.Count.ToString());
                spamassassin.StandardOutput.BaseStream.Close();

                // Read the entire stderr buffer, place it in a file if there's anything to it
                Byte[] outErrorBytes = ReadFully(spamassassin.StandardError.BaseStream);
                this.logger.debug("Read STDERR from spamassassin. BYTES=" + outErrorBytes.Length.ToString());
                if (outErrorBytes.Length > 0)
                {
                    this.logger.error("Error From SpamAssassin: " + outErrorBytes.ToString());
                }
                spamassassin.StandardError.BaseStream.Close();

                // Wait for process to exit
                spamassassin.WaitForExit();

                // Find a header
                int flagStart  = ByteSearch.Locate(outBytes.ToArray(), scoreNeedle, 0);
                int scoreEnd   = -1;
                int scoreStart = 0;

                // Check if we found the start of the header
                if (flagStart > -1)
                {
                    scoreStart = flagStart + scoreNeedle.Length;
                    scoreEnd   = ByteSearch.Locate(outBytes.ToArray(), newlineNeedle, scoreStart);
                }
                else
                {
                    this.logger.warning("Could not find start of score in message.");
                }

                // Check if we found the end of the header
                if (scoreEnd > -1)
                {
                    Byte[] scoreBytes = outBytes.GetRange(scoreStart, scoreEnd - scoreStart).ToArray();
                    try
                    {
                        score = Double.Parse(new String(scoreBytes.Select(b => (Char)b).ToArray()).Trim());
                    }
                    catch (Exception e)
                    {
                        this.logger.warning("Could not parse score. Exception:" + e.Message);
                    }
                }
                else
                {
                    this.logger.warning("Could not find end of score in message.");
                }

                // If we found a score check it and process it
                if (score != null)
                {
                    if (score >= this.settings.RejectThreshold)
                    {
                        this.logger.info("Score(" + score.ToString() + ") above threshold(" + this.settings.RejectThreshold.ToString() + "), flagging for discard.");

                        outBytes.InsertRange(flagStart, discardFlag);
                    }
                    else
                    {
                        this.logger.info("Score(" + score.ToString() + ") below threshold(" + this.settings.RejectThreshold.ToString() + "), passing.");
                    }
                }

                // Write the message back to SpamAssassin
                Byte[] writeBytes = outBytes.ToArray();
                Stream messageOut = eodArgs.MailItem.GetMimeWriteStream();
                this.logger.debug("Writing message to MailItem. BYTES=" + writeBytes.Length.ToString());
                messageOut.Write(writeBytes, 0, writeBytes.Length);
                messageOut.Close();
            }
            catch (Exception e)
            {
                this.logger.fatal("Exception Detected");
                this.logger.fatal(e.ToString());
            }
            finally
            {
                this.logger.flush();
            }
        }
        /// <summary>
        /// Handles processing the message once the end of the DATA SMTP stream is sent.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="eodArgs"></param>
        public void OnEndOfDataHandler(ReceiveEventSource source, EndOfDataEventArgs eodArgs)
        {
            Byte[] newlineNeedle = Encoding.ASCII.GetBytes("\n");
            Byte[] scoreNeedle = Encoding.ASCII.GetBytes("X-Spam-Score: ");
            Byte[] discardFlag = Encoding.ASCII.GetBytes("X-Spam-Discard: YES\n");
            Byte[] recievedNeedle = Encoding.ASCII.GetBytes("Received: ");
            Byte[] indentedLineNeedle = Encoding.ASCII.GetBytes(" ");
            Nullable<Double> score = null;

            this.logger.debug("OnEndOfDataHandler Called");

            // Wrap everything in a Try. This makes sure that even if something fails the message still passes through
            try
            {
                this.logger.info("OnEndOfDataHandler Info: FROM=" + eodArgs.MailItem.FromAddress.ToString() + ", REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString());

                // Check to make sure SpamAssassin exists at the path it's supposed to
                if (!System.IO.File.Exists(this.settings.SpamassassinPath))
                {
                    this.logger.fatal("Spamassassin does not exist at path: '" + this.settings.SpamassassinPath + "'. Bypassing.");
                    this.logger.flush();
                    return;
                }

                // Check to see if this is an internal message
                if (!eodArgs.SmtpSession.IsExternalConnection)
                {
                    foreach (EnvelopeRecipient recipient in eodArgs.MailItem.Recipients)
                    {
                        if (recipient.Address.LocalPart.IndexOf("HealthMailbox") == 0)
                        {
                            this.logger.info("Health Mailbox found in recipients. Bypassing.");
                            this.logger.flush();
                        }
                    }
                    this.logger.info("Internal Connection Found. Bypassing.");
                    this.logger.flush();
                }

                // Is the message too big?
                if (eodArgs.MailItem.MimeStreamLength > this.settings.MaxMessageSize)
                {
                    this.logger.warning("Message is too large. Increase MaxMessageSize to scan larger messages. MAXSIZE=" + this.settings.MaxMessageSize.ToString() + ", MESSAGESIZE=" + eodArgs.MailItem.MimeStreamLength.ToString());
                    this.logger.flush();
                }

                // Get the message stream
                Stream message = eodArgs.MailItem.GetMimeReadStream();
                List<Byte> messageBytes = new List<Byte>(ReadFully(message));
                byte[] messageByteArray = messageBytes.ToArray();
                message.Close();
                this.logger.debug("Message Stream Retrieved. BYTES=" + messageByteArray.Length.ToString());

                // Skip the top number of recieved lines
                int linestart = 0;
                int lineend = 0;
                int linestartmatch = 0;
                for (int i = 0; i < this.settings.SkipRecieved; i++)
                {
                    this.logger.debug("Skipping #" + i.ToString() + " Recieved line");
                    // Find the first instance of the Recieved header
                    linestart = ByteSearch.Locate(messageByteArray, recievedNeedle, 0);
                    // Loop until we find a line that doesn't start with a space.
                    do
                    {
                        lineend = ByteSearch.Locate(messageByteArray, newlineNeedle, linestart);
                        this.logger.debug("Located Line End: " + lineend.ToString());
                        linestartmatch = ByteSearch.Locate(messageByteArray, indentedLineNeedle, lineend);
                        this.logger.debug("Located LineStartMatch:" + linestartmatch.ToString());
                        messageBytes.RemoveRange(linestart, lineend - linestart + 1);
                        messageByteArray = messageBytes.ToArray();

                    } while (linestartmatch == lineend + 1);

                    this.logger.debug("Finished Skipping #" + i.ToString());

                }

                // Run spamassassin while piping stdin/stdout
                this.logger.debug("Starting SpamAssassin Process. PATH='" + this.settings.SpamassassinPath + "', ARGS='" + this.settings.SpamassassinArgs + "'");
                Process spamassassin = new Process();
                spamassassin.StartInfo.UseShellExecute = false;
                spamassassin.StartInfo.FileName = this.settings.SpamassassinPath;
                spamassassin.StartInfo.WorkingDirectory = Path.GetDirectoryName(spamassassin.StartInfo.FileName);
                spamassassin.StartInfo.Arguments = ("-s " + this.settings.MaxMessageSize + " " + this.settings.SpamassassinArgs).Trim();
                spamassassin.StartInfo.RedirectStandardInput = true;
                spamassassin.StartInfo.RedirectStandardOutput = true;
                spamassassin.StartInfo.RedirectStandardError = true;
                spamassassin.Start();
                this.logger.debug("Started SpamAssassin Process. PID='" + spamassassin.Id.ToString() + "'");

                // Copy the message into stdio using a byte for byte copy
                this.logger.debug("Copying message to Spamassassin. BYTES=" + messageByteArray.Length.ToString());
                spamassassin.StandardInput.BaseStream.Write(messageByteArray, 0, messageByteArray.Length);
                spamassassin.StandardInput.BaseStream.Flush();
                spamassassin.StandardInput.BaseStream.Close();

                // Read the entire output buffer, put it into a list for easy manipulation
                List<Byte> outBytes = new List<Byte>(ReadFully(spamassassin.StandardOutput.BaseStream));
                this.logger.debug("Read STDOUT from spamassassin. BYTES=" + outBytes.Count.ToString());
                spamassassin.StandardOutput.BaseStream.Close();

                // Read the entire stderr buffer, place it in a file if there's anything to it
                Byte[] outErrorBytes = ReadFully(spamassassin.StandardError.BaseStream);
                this.logger.debug("Read STDERR from spamassassin. BYTES=" + outErrorBytes.Length.ToString());
                if (outErrorBytes.Length > 0)
                {
                    this.logger.error("Error From SpamAssassin: " + outErrorBytes.ToString());
                }
                spamassassin.StandardError.BaseStream.Close();

                // Wait for process to exit
                spamassassin.WaitForExit();

                // Find a header
                int flagStart = ByteSearch.Locate(outBytes.ToArray(), scoreNeedle, 0);
                int scoreEnd = -1;
                int scoreStart = 0;

                // Check if we found the start of the header
                if (flagStart > -1)
                {
                    scoreStart = flagStart + scoreNeedle.Length;
                    scoreEnd = ByteSearch.Locate(outBytes.ToArray(), newlineNeedle, scoreStart);
                } else {
                    this.logger.warning("Could not find start of score in message.");
                }

                // Check if we found the end of the header
                if (scoreEnd > -1)
                {
                    Byte[] scoreBytes = outBytes.GetRange(scoreStart, scoreEnd - scoreStart).ToArray();
                    try
                    {
                        score = Double.Parse(new String(scoreBytes.Select(b => (Char)b).ToArray()).Trim());
                    }
                    catch(Exception e)
                    {
                        this.logger.warning("Could not parse score. Exception:" + e.Message);
                    }
                }
                else
                {
                    this.logger.warning("Could not find end of score in message.");
                }

                // If we found a score check it and process it
                if(score != null) {
                    if (score >= this.settings.RejectThreshold)
                    {
                        this.logger.info("Score(" + score.ToString() + ") above threshold(" + this.settings.RejectThreshold.ToString() + "), flagging for discard.");

                        outBytes.InsertRange(flagStart, discardFlag);
                    }
                    else
                    {
                        this.logger.info("Score(" + score.ToString() + ") below threshold(" + this.settings.RejectThreshold.ToString() + "), passing.");
                    }
                }

                // Write the message back to SpamAssassin
                Byte[] writeBytes = outBytes.ToArray();
                Stream messageOut = eodArgs.MailItem.GetMimeWriteStream();
                this.logger.debug("Writing message to MailItem. BYTES=" + writeBytes.Length.ToString());
                messageOut.Write(writeBytes, 0, writeBytes.Length);
                messageOut.Close();

            }
            catch (Exception e)
            {
                this.logger.fatal("Exception Detected");
                this.logger.fatal(e.ToString());
            }
            finally
            {
                this.logger.flush();
            }
            
        }
        /// <summary>
        /// Invoked by Exchange when the entire message has been received.
        /// </summary>
        /// <param name="source">The source of this event.</param>
        /// <param name="eodArgs">The arguments for this event.</param>
        public void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs eodArgs)
        {
            Debug.WriteLine("[BodyConversion] OnEndOfDataHandler is called");

            // The purpose of this sample is to show how TextConverters can be used
            // to update the body. This sample shows how to ensure that no active
            // content, such as scripts, can pass through in a message body.

            EmailMessage message             = eodArgs.MailItem.Message;
            Stream       originalBodyContent = null;
            Stream       newBodyContent      = null;
            Encoding     encoding;
            string       charsetName;

            try
            {
                Body       body       = message.Body;
                BodyFormat bodyFormat = body.BodyFormat;

                if (!body.TryGetContentReadStream(out originalBodyContent))
                {
                    // You cannot decode the body.
                    return;
                }

                if (BodyFormat.Text == bodyFormat)
                {
                    // Plain text body. Add a disclaimer to this body.

                    charsetName = body.CharsetName;
                    if (null == charsetName ||
                        !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding))
                    {
                        // Either no charset, or charset is not supported by the system.
                        return;
                    }

                    // Create and set up the TextToText conversion object.
                    TextToText textToTextConversion = new TextToText();

                    // Don't change the body code page.
                    textToTextConversion.InputEncoding = encoding;
                    // By default, the output code page is the same as the input code page.

                    // Add a disclaimer to indicate that the body is not being filtered.
                    textToTextConversion.HeaderFooterFormat = HeaderFooterFormat.Text;
                    textToTextConversion.Footer             = "the plain text body is NOT being filtered";

                    // Open the stream to write updated content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Do the conversion. This will replace the original text.
                    // with an updated version.
                    try
                    {
                        // The easiest way to do the conversion in one step is by using the Convert
                        // method. It creates the appropriate converter stream
                        // and copies from one stream to another.
                        textToTextConversion.Convert(originalBodyContent, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }
                else if (BodyFormat.Html == bodyFormat)
                {
                    // The HTML body.

                    // Filter the original HTML to remove any scripts and other
                    // potentially unsafe content.

                    charsetName = body.CharsetName;
                    if (null == charsetName ||
                        !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding))
                    {
                        // Either no charset, or charset is not supported by the system.
                        return;
                    }

                    // Create and set up the HtmlToHtml conversion object.
                    HtmlToHtml htmlToHtmlConversion = new HtmlToHtml();

                    // Don't change the body code page.
                    htmlToHtmlConversion.InputEncoding = encoding;
                    // By default, the output code page is the same as the input code page.

                    // Set up output HTML filtering. HTML filtering will ensure that
                    // no scripts or active content can pass through.
                    htmlToHtmlConversion.FilterHtml = true;

                    // Add a disclaimer to indicate that the body is being filtered.
                    htmlToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                    htmlToHtmlConversion.Footer             = "<p><font face=\"Arial\" size=\"+1\">the HTML body is being filtered</font></p>";

                    // Open the stream to write updated content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Do the conversion. This will replace the original HTML
                    // with a filtered version.
                    try
                    {
                        // The easiest way to do the conversion in one step is by using the Convert
                        // method. It creates an appropriate converter stream
                        // and copies from one stream to another.
                        htmlToHtmlConversion.Convert(originalBodyContent, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }
                else if (BodyFormat.Rtf == bodyFormat)
                {
                    // This is compressed RTF body in a TNEF message.

                    // Compressed RTF body can contain the encapsulated original HTML to be
                    // filtered.

                    // Do not modify the message format here, just filter out
                    // potentially unsafe content. Convert RTF to HTML, filter out any
                    // unsafe HTML content, and convert the result back to RTF.

                    // Note that conversion from RTF to HTML and back to RTF can result in loss of data. Some
                    // embedded images in RTF can be lost and formatting can slightly change.

                    // First wrap the original body content, which is in a "compressed RTF" format, into
                    // a stream that will do RTF decompression. Reading from this stream
                    // will return original RTF (the same format that the Word and RichEdit controls are using).
                    ConverterStream uncompressedRtf = new ConverterStream(originalBodyContent, new RtfCompressedToRtf(), ConverterStreamAccess.Read);

                    // Create and configure the RtfToHtml conversion object.
                    RtfToHtml rtfToHtmlConversion = new RtfToHtml();

                    // Set up output HTML filtering. HTML filtering will ensure that
                    // no scripts or active content can pass through.
                    rtfToHtmlConversion.FilterHtml = true;

                    // Add a disclaimer to indicate that the body is being filtered.
                    rtfToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                    rtfToHtmlConversion.Footer             = "<p><font face=\"Arial\" size=1>the RTF body is being filtered</font></p>";

                    // Now create a wrapping TextReader object, which returns the filtered
                    // HTML converted (or extracted) from the original RTF.
                    ConverterReader html = new ConverterReader(uncompressedRtf, rtfToHtmlConversion);

                    // After you filter the HTML, convert it back to RTF. For the purposes of this sample, do not
                    // change the message format.

                    // Create and configure the HtmlToRtf conversion object.
                    HtmlToRtf htmlToRtfConversion = new HtmlToRtf();

                    // Create a wrapping stream that returns RTF converted back from filtered HTML.
                    ConverterStream filteredRtf = new ConverterStream(html, htmlToRtfConversion);

                    // Create and configure the RtfToRtfCompressed conversion object, which
                    // will compress the resulting RTF.
                    RtfToRtfCompressed rtfCompressionConversion = new RtfToRtfCompressed();

                    // Always write it back in a compressed form.
                    rtfCompressionConversion.CompressionMode = RtfCompressionMode.Compressed;

                    // Open the stream to write updated body content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Finally, perform the complete chain of conversions you set up. This
                    // will read the original compressed RTF chunk by chunk, convert it to HTML
                    // and filter scripts, then convert HTML back to RTF, compress it and write
                    // back into the current message body.
                    try
                    {
                        // Use the Convert method because it is convenient. This Convert
                        // method compresses the resulting RTF it reads from the conversion
                        // chain stream you set up and writes the result into the output stream.
                        // It saves a few lines of code that would be required to create another wrapper stream and
                        // copy from one stream to another.
                        rtfCompressionConversion.Convert(filteredRtf, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }

                else
                {
                    // Handle cases where the body format is not one of the above.
                }
            }

            finally
            {
                if (originalBodyContent != null)
                {
                    originalBodyContent.Close();
                }

                if (newBodyContent != null)
                {
                    newBodyContent.Close();
                }
            }
        }
Esempio n. 10
0
 void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs e)
 {
     Logger.Debug("[GenericExchangeTransportagent] [SmtpReceiveAgent] OnEndOfData fired...");
     _config.SmtpReceiveAgentConfig.OnEndOfData.ToList().ForEach(x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error executing ""OnEndOfData"""); } });
 }