Exemplo n.º 1
0
        /// <summary>
        /// Saves the email to the local drop folder.
        /// </summary>
        private async Task <SmtpServerTransactionAsyncResult> SaveToLocalMailboxAsync()
        {
            // Add the MAIL FROM & RCPT TO headers.
            Data = MessageManager.AddHeader(Data, new MessageHeader("X-Reciepient", string.Join("; ", RcptTo)));
            if (HasMailFrom && string.IsNullOrWhiteSpace(MailFrom))
            {
                Data = MessageManager.AddHeader(Data, new MessageHeader("X-Sender", "<>"));
            }
            else
            {
                Data = MessageManager.AddHeader(Data, new MessageHeader("X-Sender", MailFrom));
            }

            // Need to drop a copy of the message for each recipient.
            for (int i = 0; i < RcptTo.Count; i++)
            {
                // Put the messages in a subfolder for each recipient.
                // Unless the rcpt to is a return path message in which case put them all in a return-path folder
                string mailDirPath = string.Empty;

                // Bounce.
                if (RcptTo[i].StartsWith("return-", StringComparison.OrdinalIgnoreCase))
                {
                    mailDirPath = MtaParameters.BounceDropFolder;
                }

                // Abuse.
                else if (RcptTo[i].StartsWith("abuse@", StringComparison.OrdinalIgnoreCase))
                {
                    mailDirPath = MtaParameters.AbuseDropFolder;
                }

                // Postmaster.
                else if (RcptTo[i].StartsWith("postmaster@", StringComparison.OrdinalIgnoreCase))
                {
                    mailDirPath = MtaParameters.PostmasterDropFolder;
                }

                // Must be feedback loop.
                else
                {
                    mailDirPath = MtaParameters.FeedbackLoopDropFolder;
                }


                // Ensure the directory exists by always calling create.
                Directory.CreateDirectory(mailDirPath);

                // Write the Email File.
                using (StreamWriter sw = new StreamWriter(Path.Combine(mailDirPath, Guid.NewGuid().ToString()) + ".eml"))
                {
                    await sw.WriteAsync(Data);
                }
            }

            return(SmtpServerTransactionAsyncResult.SuccessMessageDelivered);
        }
Exemplo n.º 2
0
        public void AddHeader()
        {
            string msg = @"Received: by mail-ve0-f170.google.com with SMTP id c14so7342138vea.29
        for <*****@*****.**>; Thu, 12 Sep 2013 08:55:44 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:date:message-id:subject:from:to
         :content-type;
        bh=g3zLYH4xKxcPrHOD18z9YfpQcnk/GaJedfustWU5uGs=;
        b=QQp2spZaT8t1uP2qlmFDNRy5SMCkPfyAcwWAyTH8SbWtBMZ6hSssOHTdYEPb6aPbBQ
         qFquL9n20dtfSLU47+OLtB+cOoOtAt1FACRWN42x/V608OEAeu25KjTgnD3LFBvn482y
         PWmlpv8MlyulZvqT33dgp0C7Wb4HN5jGLgRajteAFfyiK+Hn0ouP+Q/WdWFm3SAiB4e2
         VVEPV+8hh79e3Bpwqjjnlu3xL8gG+kgqGKnzv7XsuSH7QdO7KDiVQLiWqvPv3je15eN5
         6fQW6hfnD9vU3oJtu4Qxnxw2LCSC8Ble2JVIqFuVlljwzVERv00b8GlpMUy4VoSv/oxZ
         jR9Q==
X-Gm-Message-State: ALoCoQkJ3V6JKWYCk5sVgPWozY51PLGpZk+oEFXvfjTeRXLdEwuyJt1ZZGIF8VY7cV9ZQkkKm5/U
MIME-Version: 1.0
X-Received: by 10.58.207.103 with SMTP id lv7mr1139399vec.33.1379000866633;
 Thu, 12 Sep 2013 08:47:46 -0700 (PDT)
Received: by 10.221.57.135 with HTTP; Thu, 12 Sep 2013 08:47:46 -0700 (PDT)
Date: Thu, 12 Sep 2013 16:47:46 +0100
Message-ID: <*****@*****.**>
Subject: test
From: Redacted <*****@*****.**>
To: [email protected]
Content-Type: text/plain; charset=UTF-8

test";
            // Test with header value thats short enougth to not need folding.
            string returned = MessageManager.AddHeader(msg, new MessageHeader("Test", "test"));

            Assert.AreEqual("Test: test" + System.Environment.NewLine + msg, returned);

            // Test with header value that is longer than 78 but can't be folded as it contains no white space.
            returned = MessageManager.AddHeader(msg, new MessageHeader("Test", "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest"));
            Assert.AreEqual(@"Test:
 testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest" + System.Environment.NewLine + msg, returned);

            // Test with long value that can be folded.
            returned = MessageManager.AddHeader(msg, new MessageHeader("Test", "test testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest"));
            Assert.AreEqual(@"Test: test
 testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest" + System.Environment.NewLine + msg, returned);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Adds a header to the message data.
 /// </summary>
 /// <param name="name">The header name.</param>
 /// <param name="value">Value for the header.</param>
 public void AddHeader(string name, string value)
 {
     Data = MessageManager.AddHeader(Data, new MessageHeader(name, value));
 }
Exemplo n.º 4
0
        /// <summary>
        /// Queues the email for relaying.
        /// </summary>
        private async Task <SmtpServerTransactionAsyncResult> QueueForRelayingAsync()
        {
            // The email is for relaying.
            Guid messageID = Guid.NewGuid();

            // Look for any MTA control headers.
            MessageHeaderCollection headers = MessageManager.GetMessageHeaders(Data);

            // Will not be null if the SendGroupID header was present.
            MessageHeader ipGroupHeader = headers.SingleOrDefault(m => m.Name.Equals(MessageHeaderNames.SendGroupID, StringComparison.OrdinalIgnoreCase));

            // Parameter will hold the MtaIPGroup that will be used to relay this message.
            VirtualMta.VirtualMtaGroup mtaGroup = null;
            int ipGroupID = 0;

            if (ipGroupHeader != null)
            {
                if (int.TryParse(ipGroupHeader.Value, out ipGroupID))
                {
                    mtaGroup = VirtualMta.VirtualMtaManager.GetVirtualMtaGroup(ipGroupID);
                }
            }

            #region Look for a send id, if one doesn't exist create it.
            MessageHeader sendIdHeader   = headers.SingleOrDefault(h => h.Name.Equals(MessageHeaderNames.SendID, StringComparison.OrdinalIgnoreCase));
            int           internalSendId = -1;
            if (sendIdHeader != null)
            {
                Sends.Send sndID = await Sends.SendManager.Instance.GetSendAsync(sendIdHeader.Value);

                if (sndID.SendStatus == SendStatus.Discard)
                {
                    return(SmtpServerTransactionAsyncResult.FailedSendDiscarding);
                }
                internalSendId = sndID.InternalID;
            }
            else
            {
                Sends.Send sndID = await Sends.SendManager.Instance.GetDefaultInternalSendIdAsync();

                if (sndID.SendStatus == SendStatus.Discard)
                {
                    return(SmtpServerTransactionAsyncResult.FailedSendDiscarding);
                }
                internalSendId = sndID.InternalID;
            }
            #endregion

            #region Generate Return Path
            string returnPath = string.Empty;

            // Can only return path to messages with one rcpt to
            if (RcptTo.Count == 1)
            {
                // Need to check to see if the message contains a return path overide domain.
                MessageHeader returnPathDomainOverrideHeader = headers.SingleOrDefault(h => h.Name.Equals(MessageHeaderNames.ReturnPathDomain, StringComparison.OrdinalIgnoreCase));

                if (returnPathDomainOverrideHeader != null &&
                    MtaParameters.LocalDomains.Count(d => d.Hostname.Equals(returnPathDomainOverrideHeader.Value, StringComparison.OrdinalIgnoreCase)) > 0)
                {
                    // The message contained a local domain in the returnpathdomain
                    // header so use it instead of the default.
                    returnPath = ReturnPathManager.GenerateReturnPath(RcptTo[0], internalSendId, returnPathDomainOverrideHeader.Value);
                }
                else
                {
                    // The message didn't specify a return path overide or it didn't
                    // contain a localdomain so use the default.
                    returnPath = ReturnPathManager.GenerateReturnPath(RcptTo[0], internalSendId);
                }

                // Insert the return path header.
                Data = MessageManager.AddHeader(Data, new MessageHeader("Return-Path", "<" + returnPath + ">"));
            }
            else
            {
                // multiple rcpt's so can't have unique return paths, use generic mail from.
                returnPath = MailFrom;
            }
            #endregion

            #region Generate a message ID header
            string msgIDHeaderVal = "<" + messageID.ToString("N") + MailFrom.Substring(MailFrom.LastIndexOf("@")) + ">";

            // If there is already a message header, remove it and add our own. required for feedback loop processing.
            if (headers.Count(h => h.Name.Equals("Message-ID", StringComparison.OrdinalIgnoreCase)) > 0)
            {
                Data = MessageManager.RemoveHeader(Data, "Message-ID");
            }

            // Add the new message-id header.
            Data = MessageManager.AddHeader(Data, new MessageHeader("Message-ID", msgIDHeaderVal));
            #endregion

            // Remove any control headers.
            headers = new MessageHeaderCollection(headers.Where(h => h.Name.StartsWith(MessageHeaderNames.HeaderNamePrefix, StringComparison.OrdinalIgnoreCase)));
            foreach (MessageHeader header in headers)
            {
                Data = MessageManager.RemoveHeader(Data, header.Name);
            }

            // If the MTA group doesn't exist or it's not got any IPs, use the default.
            if (mtaGroup == null ||
                mtaGroup.VirtualMtaCollection.Count == 0)
            {
                ipGroupID = VirtualMta.VirtualMtaManager.GetDefaultVirtualMtaGroup().ID;
            }

            // Attempt to Enqueue the Email for Relaying.
            if (!QueueManager.Instance.Enqueue(messageID, ipGroupID, internalSendId, returnPath, RcptTo.ToArray(), Data))
            {
                return(SmtpServerTransactionAsyncResult.FailedToEnqueue);
            }

            return(SmtpServerTransactionAsyncResult.SuccessMessageQueued);
        }