/// <summary> /// Creates text/plain MIME entity. /// </summary> /// <param name="transferEncoding">Content transfer encoding.</param> /// <param name="charset">Charset to use to encode text. If not sure, utf-8 is recommended.</param> /// <param name="text">Text.</param> /// <returns>Returns created entity.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>transferEncoding</b>, <b>charset</b> or <b>text</b> is null reference.</exception> /// <exception cref="NotSupportedException">Is raised when body contains not supported Content-Transfer-Encoding.</exception> public static MIME_Entity CreateEntity_Text_Plain(string transferEncoding,Encoding charset,string text) { if(transferEncoding == null){ throw new ArgumentNullException("transferEncoding"); } if(charset == null){ throw new ArgumentNullException("charset"); } if(text == null){ throw new ArgumentNullException("text"); } MIME_Entity retVal = new MIME_Entity(); MIME_b_Text body = new MIME_b_Text(MIME_MediaTypes.Text.plain); retVal.Body = body; body.SetText(transferEncoding,charset,text); return retVal; }
/// <summary> /// Creates text/html MIME entity. /// </summary> /// <param name="transferEncoding">Content transfer encoding.</param> /// <param name="charset">Charset to use to encode text. If not sure, utf-8 is recommended.</param> /// <param name="text">Text.</param> /// <returns>Returns created entity.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>transferEncoding</b>, <b>charset</b> or <b>text</b> is null reference.</exception> /// <exception cref="NotSupportedException">Is raised when body contains not supported Content-Transfer-Encoding.</exception> public static MIME_Entity CreateEntity_Text_Html(string transferEncoding, Encoding charset, string text) { if (transferEncoding == null) { throw new ArgumentNullException("transferEncoding"); } if (charset == null) { throw new ArgumentNullException("charset"); } if (text == null) { throw new ArgumentNullException("text"); } MIME_Entity retVal = new MIME_Entity(); MIME_b_Text body = new MIME_b_Text(MIME_MediaTypes.Text.html); retVal.Body = body; body.SetText(transferEncoding, charset, text); return(retVal); }
/// <summary> /// Generates message parsing failed message. /// </summary> /// <param name="message">Message stream.</param> /// <returns>Returns message parsing failed message.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>message</b> is null reference.</exception> public static Mail_Message GenerateBadMessage(Stream message) { if(message == null){ throw new ArgumentNullException("message"); } Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; msg.From = new Mail_t_MailboxList(); msg.From.Add(new Mail_t_Mailbox("system","system")); msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox("system","system")); msg.Subject = "[BAD MESSAGE] Bad message, message parsing failed !"; //--- multipart/mixed ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- text/plain --------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Bad message, message parsing failed.\r\n\r\nOriginal message attached as 'data.eml'\r\n"); multipartMixed.BodyParts.Add(entity_text_plain); //--- application/octet-stream -------------------------------------------------------------------------------------- MIME_Entity entity_application_octet_stream = new MIME_Entity(); entity_application_octet_stream.ContentDisposition = new MIME_h_ContentDisposition("attachment"); entity_application_octet_stream.ContentDisposition.Param_FileName = "data.eml"; MIME_b_Application application_octet_stream = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream); entity_application_octet_stream.Body = application_octet_stream; application_octet_stream.SetData(message,"base64"); multipartMixed.BodyParts.Add(entity_application_octet_stream); return msg; }
/// <summary> /// Stores message to specified folder. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param> /// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param> /// <param name="date">Recieve date.</param> /// <param name="flags">Message flags.</param> public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'p' or 'i' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(msgStream); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'p' or 'i' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Store message MemoryStream msgMemStream = new MemoryStream(); Net_Utils.StreamCopy(msgStream,msgMemStream,32000); byte[] messageData = msgMemStream.ToArray(); byte[] topLines = GetTopLines(new MemoryStream(messageData),50); Mail_Message message = null; try{ msgStream.Position = 0; message = Mail_Message.ParseFromByte(messageData); } catch(Exception x){ message = new Mail_Message(); message.MimeVersion = "1.0"; message.MessageID = MIME_Utils.CreateMessageID(); message.Date = DateTime.Now; message.From = new Mail_t_MailboxList(); message.From.Add(new Mail_t_Mailbox("system","system")); message.To = new Mail_t_AddressList(); message.To.Add(new Mail_t_Mailbox("system","system")); message.Subject = "[BAD MESSAGE] Bad message, message parsing failed !"; //--- multipart/mixed ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); message.Body = multipartMixed; //--- text/plain --------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Bad message, message parsing failed.\r\n\r\n"); multipartMixed.BodyParts.Add(entity_text_plain); } byte[] envelope = System.Text.Encoding.Default.GetBytes(IMAP_Envelope.ConstructEnvelope(message)); byte[] body = System.Text.Encoding.Default.GetBytes(IMAP_BODY.ConstructBodyStructure(message,false)); using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){ sqlCmd.AddParameter("_userName" ,NpgsqlDbType.Varchar ,folderOwnerUser); sqlCmd.AddParameter("_folder" ,NpgsqlDbType.Varchar ,folder); sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar ,Guid.NewGuid().ToString()); sqlCmd.AddParameter("_size" ,NpgsqlDbType.Integer ,messageData.Length); sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer ,(int)flags); sqlCmd.AddParameter("_date" ,NpgsqlDbType.Timestamp ,date); sqlCmd.AddParameter("_topLines" ,NpgsqlDbType.Bytea ,topLines); sqlCmd.AddParameter("_data" ,NpgsqlDbType.Bytea ,messageData); sqlCmd.AddParameter("_imapEnvelope" ,NpgsqlDbType.Bytea ,envelope); sqlCmd.AddParameter("_imapBody" ,NpgsqlDbType.Bytea ,body); DataSet ds = sqlCmd.Execute(); } }
public void Send(ChannelMessage message) { var creds = CredentialsProvider.GetCredentials().ToNetworkCredential(); Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Subject = message.Context; msg.From = message.From.ToMailBoxList(); msg.ReplyTo = message.ReturnTo == null ? message.From.ToAddressList() : message.ReturnTo.ToAddressList(); if (String.IsNullOrEmpty(message.InReplyTo) == false) msg.InReplyTo = message.InReplyTo; msg.To = new Mail_t_AddressList(); foreach (var address in message.To) msg.To.Add(address.ToMailBox()); msg.Cc = new Mail_t_AddressList(); foreach (var address in message.CC) msg.Cc.Add(address.ToMailBox()); //--- multipart/mixed ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- multipart/alternative ----------------------------------------------------------------------------------------- MIME_Entity entity_multipartAlternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipartAlternative.Body = multipartAlternative; multipartMixed.BodyParts.Add(entity_multipartAlternative); //--- text/plain ---------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; // Add text body if there is any if (message.BodyText != null && message.BodyText.Length > 0) { var bodyText = message.BodyText.ReadString(); // Make sure there is a newline at the end of our text, otherwise it will screw up // our multipart data format if (!bodyText.EndsWith(Environment.NewLine)) bodyText = bodyText + Environment.NewLine; text_plain.SetText(MIME_TransferEncodings.SevenBit, Encoding.UTF8, bodyText); } multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ------------------------------------------------------------------------------------------------------ MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; if (message.BodyHtml != null && message.BodyHtml.Length > 0) { var bodyHtml = message.BodyHtml.ReadString(); // Make sure there is a newline at the end of our text, otherwise it will screw up // our multipart data format if (!bodyHtml.EndsWith(Environment.NewLine)) bodyHtml = bodyHtml + Environment.NewLine; text_html.SetText(MIME_TransferEncodings.SevenBit, Encoding.UTF8, bodyHtml); } multipartAlternative.BodyParts.Add(entity_text_html); foreach (var channelAttachment in message.Attachments) { MIME_b_Application attachmentBody = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream); MIME_Entity attachment = new MIME_Entity(); attachment.Body = attachmentBody; // Has to happen before the following lines of code multipartMixed.BodyParts.Add(attachment); attachment.ContentType = new MIME_h_ContentType(MimeHelper.GetMimeType(channelAttachment.Filename)); attachment.ContentType.Param_Name = channelAttachment.Filename; MIME_h_ContentDisposition contentDisposition = new MIME_h_ContentDisposition(DispositionTypeNames.Attachment); contentDisposition.Param_FileName = channelAttachment.Filename; attachment.ContentDisposition = contentDisposition; attachment.ContentTransferEncoding = TransferEncoding.Base64.ToString(); attachmentBody.SetData(channelAttachment.ContentStream, MIME_TransferEncodings.Base64); } // Inject headers if (!String.IsNullOrEmpty(message.MessageIdentifier)) msg.Header.Add(new MIME_h_Unstructured("x-i2mp-messageid", message.MessageIdentifier)); //if (!String.IsNullOrEmpty(message.Metadata.i2mpFlow)) // msg.Header.Add(new MIME_h_Unstructured("x-i2mp-flow", message.Metadata.i2mpFlow)); //if (!String.IsNullOrEmpty(message.Metadata.i2mpReference)) // mailMessage.Headers.Add("X-i2mp-ref", message.Metadata.i2mpReference); //if (!String.IsNullOrEmpty(message.Metadata.i2mpSequence)) // mailMessage.Headers.Add("X-i2mp-seq", message.Metadata.i2mpSequence); //if (!String.IsNullOrEmpty(message.Metadata.i2mpRelation)) // mailMessage.Headers.Add("X-i2mp-rel", message.Metadata.i2mpRelation); //if (!String.IsNullOrEmpty(message.Metadata.i2mpRelationId)) // mailMessage.Headers.Add("X-i2mp-rel-id", message.Metadata.i2mpRelationId); // Send message try { SMTP_Client client = new SMTP_Client(); if ("/Settings/Channels/LoggerEnabled".AsKey(false)) client.Logger = new LumiSoft.Net.Log.Logger(); // todo push this logic into the smtp client implementation itself if (Hostname == "smtp.live.com") { // Hack for hotmail, first do a connect with no secured channel, // then a STARTTLS client.Connect(Hostname, Port, false); client.StartTLS(); } else { client.Connect(Hostname, Port, IsSecured); } client.Authenticate(creds.UserName, creds.Password); using (MemoryStream ms = new MemoryStream()) { client.MailFrom(msg.From[0].Address, -1); msg.ToStream(ms, new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8); // Reset stream ms.Seek(0, SeekOrigin.Begin); foreach (var address in message.To) client.RcptTo(address.Address); foreach (var address in message.CC) client.RcptTo(address.Address); foreach (var address in message.BCC) client.RcptTo(address.Address); try { client.SendMessage(ms); } finally { client.Dispose(); } } } catch(SmtpFailedRecipientsException e) { throw new ChannelFunctionalException(e.Message, e) { DoNotRetry = true }; } catch (SmtpException e) { throw new ChannelFunctionalException(e.Message, e); } catch (Exception e) { throw new ChannelFunctionalException(e.Message, e); } }
private Mail_Message Create_PlainText_Html_Attachment_Image(string mailTo, string mailFrom, string mailFromDisplay) { Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; msg.From = new Mail_t_MailboxList(); msg.From.Add(new Mail_t_Mailbox(mailFromDisplay, mailFrom)); msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox(mailTo, mailTo)); msg.Subject = "Test Send Mail"; //设置回执通知 //string notifyEmail = SystemConfig.Default.DispositionNotificationTo; //if (!string.IsNullOrEmpty(notifyEmail) && ValidateUtil.IsEmail(notifyEmail)) //{ // msg.DispositionNotificationTo = new Mail_t_Mailbox(notifyEmail, notifyEmail); //} #region MyRegion //--- multipart/mixed ----------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- multipart/alternative ----------------------------- MIME_Entity entity_multipartAlternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipartAlternative.Body = multipartAlternative; multipartMixed.BodyParts.Add(entity_multipartAlternative); //--- text/plain ---------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; //普通文本邮件内容,如果对方的收件客户端不支持HTML,这是必需的 string plainTextBody = "如果你邮件客户端不支持HTML格式,或者你切换到“普通文本”视图,将看到此内容"; //if (!string.IsNullOrEmpty(SystemConfig.Default.PlaintTextTips)) //{ // plainTextBody = SystemConfig.Default.PlaintTextTips; //} text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, plainTextBody); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ----------------------------------------- string htmlText = "<html>这是一份测试邮件,来自<font color=red><b>厦门至正测试程序</b></font></html>"; MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, htmlText); multipartAlternative.BodyParts.Add(entity_text_html); //--- application/octet-stream ------------------------- //foreach (string attach in mailInfo.Attachments) //{ // multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(attach)); //} //foreach (string imageFile in mailInfo.EmbedImages) //{ //MIME_Entity entity_image = new MIME_Entity(); //entity_image.ContentDisposition = new MIME_h_ContentDisposition(MIME_DispositionTypes.Inline); //string fileName = "D:\\test.txt"; // DirectoryUtil.GetFileName(imageFile, true); //entity_image.ContentID = (new Guid()).ToString().Replace('-', '.'); //BytesTools.BytesToHex(Encoding.Default.GetBytes(fileName)); //MIME_b_Image body_image = new MIME_b_Image(MIME_MediaTypes.Image.jpeg); //entity_image.Body = body_image; //body_image.SetDataFromFile("D:\\test.txt", MIME_TransferEncodings.Base64); //multipartMixed.BodyParts.Add(entity_image); //} #endregion return msg; }
/// <summary> /// Creates Mime message based on UI data. /// </summary> private Mail_Message CreateMessage() { Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; msg.From = Mail_h_MailboxList.Parse("From: " + m_pFrom.Text).Addresses; msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox(m_pFolder.User.FullName,m_pFolder.User.FullName + "@localhost")); msg.Subject = m_pSubject.Text; //--- multipart/mixed ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- multipart/alternative ----------------------------------------------------------------------------------------- MIME_Entity entity_multipartAlternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipartAlternative.Body = multipartAlternative; multipartMixed.BodyParts.Add(entity_multipartAlternative); //--- text/plain ---------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,m_pText.Text); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ------------------------------------------------------------------------------------------------------ MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,RtfToHtml()); multipartAlternative.BodyParts.Add(entity_text_html); //--- application/octet-stream ----------------------------------------------------------------------------------------------- foreach(ListViewItem item in m_pAttachments.Items){ multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(item.Tag.ToString())); } return msg; }
private void m_pOk_Click(object sender, EventArgs e) { Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; msg.From = Mail_h_MailboxList.Parse("From: " + m_pFrom.Text).Addresses; if(!string.IsNullOrEmpty(m_pTo.Text)){ msg.To = Mail_h_AddressList.Parse("To: " + m_pTo.Text).Addresses; } msg.Subject = m_pSubject.Text; MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); msg.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,m_pBodyText.Text); m_Message = msg.ToString(new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.B,Encoding.UTF8),Encoding.UTF8); this.DialogResult = DialogResult.OK; }
private static void CreateBodyPart(Mail_Message msg, string BodyText) { //--- multipart/mixed ----------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- multipart/alternative ----------------------------- MIME_Entity entity_multipartAlternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipartAlternative.Body = multipartAlternative; multipartMixed.BodyParts.Add(entity_multipartAlternative); //--- text/plain ---------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; entity_text_plain.ContentTransferEncoding = MIME_TransferEncodings.Base64; //普通文本邮件内容,如果对方的收件客户端不支持HTML,这是必需的 string plainTextBody = "如果你邮件客户端不支持HTML格式,或者你切换到“普通文本”视图,将看到此内容"; //if (!string.IsNullOrEmpty(SystemConfig.Default.PlaintTextTips)) //{ // plainTextBody = SystemConfig.Default.PlaintTextTips; //} text_plain.SetText(MIME_TransferEncodings.Base64, Encoding.UTF8, plainTextBody); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ----------------------------------------- string htmlText = "<html>" + BodyText.Replace("\r\n", "<br>") + "</html>"; MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, htmlText); multipartAlternative.BodyParts.Add(entity_text_html); }
/// <summary> /// Creates delivery status notifications(DSN) message. /// </summary> /// <param name="to">DSN message To.</param> /// <param name="subject">DSN message subject.</param> /// <param name="rtfText">DSN message RTF body text.</param> /// <param name="envelopeID">Envelope ID(MAIL FROM: ENVID).</param> /// <param name="arrivalDate">Message arrival date.</param> /// <param name="receivedFromMTA">The remote host EHLo name from where messages was received.</param> /// <param name="reportingMTA">Reporting MTA name.</param> /// <param name="originalRecipient">Original recipient(RCPT TO: ORCTP).</param> /// <param name="finalRecipient">Final recipient.</param> /// <param name="action">DSN action.</param> /// <param name="statusCode_text">Remote SMTP status code with text.</param> /// <param name="remoteMTA">Remote MTA what returned <b>statusCode_text</b>.</param> /// <param name="lastAttempt">Last delivery attempt.</param> /// <param name="retryUntil">Date time how long server will attempt to deliver message.</param> /// <param name="ret">Specifies what original message part are renturned.</param> /// <param name="message">Original message.</param> /// <returns>Returns created DSN message.</returns> public static Mail_Message CreateDsnMessage(string to,string subject,string rtfText,string envelopeID,DateTime arrivalDate,string receivedFromMTA,string reportingMTA,string originalRecipient,string finalRecipient,string action,string statusCode_text,string remoteMTA,DateTime lastAttempt,DateTime retryUntil,SMTP_DSN_Ret ret,Mail_Message message) { // For more info, see RFC 3464. // Ensure that all line-feeds are CRLF. rtfText = rtfText.Replace("\r\n","\n").Replace("\n","\r\n"); Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.Date = DateTime.Now; msg.From = new Mail_t_MailboxList(); msg.From.Add(new Mail_t_Mailbox("Mail Delivery Subsystem","postmaster@local")); msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox(null,to)); msg.Subject = subject; //--- multipart/report ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartReport = new MIME_h_ContentType(MIME_MediaTypes.Multipart.report); contentType_multipartReport.Parameters["report-type"] = "delivery-status"; contentType_multipartReport.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartReport multipartReport = new MIME_b_MultipartReport(contentType_multipartReport); msg.Body = multipartReport; //--- multipart/alternative ----------------------------------------------------------------------------------------- MIME_Entity entity_multipart_alternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipart_alternative.Body = multipartAlternative; multipartReport.BodyParts.Add(entity_multipart_alternative); //--- text/plain --------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,SCore.RtfToText(rtfText)); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ----------------------------------------------------------------------------------------------------- MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,SCore.RtfToHtml(rtfText)); multipartAlternative.BodyParts.Add(entity_text_html); //--- message/delivery-status MIME_Entity entity_message_deliveryStatus = new MIME_Entity(); MIME_b_Message body_message_deliveryStatus = new MIME_b_Message(MIME_MediaTypes.Message.delivery_status); entity_message_deliveryStatus.Body = body_message_deliveryStatus; StringBuilder dsnText = new StringBuilder(); if(!string.IsNullOrEmpty(envelopeID)){ dsnText.Append("Original-Envelope-Id: " + envelopeID + "\r\n"); } dsnText.Append("Arrival-Date: " + MIME_Utils.DateTimeToRfc2822(arrivalDate) + "\r\n"); if(!string.IsNullOrEmpty(receivedFromMTA)){ dsnText.Append("Received-From-MTA: dns; " + receivedFromMTA + "\r\n"); } dsnText.Append("Reporting-MTA: dns; " + reportingMTA + "\r\n"); dsnText.Append("\r\n"); if(!string.IsNullOrEmpty(originalRecipient)){ dsnText.Append("Original-Recipient: " + originalRecipient + "\r\n"); } dsnText.Append("Final-Recipient: rfc822;" + finalRecipient + "" + "\r\n"); dsnText.Append("Action: " + action + "\r\n"); dsnText.Append("Status: " + statusCode_text.Substring(0,1) + ".0.0" + "\r\n"); if(!string.IsNullOrEmpty(statusCode_text)){ dsnText.Append("Diagnostic-Code: smtp; " + statusCode_text + "\r\n"); } if(!string.IsNullOrEmpty(remoteMTA)){ dsnText.Append("Remote-MTA: dns; " + remoteMTA + "\r\n"); } if(lastAttempt != DateTime.MinValue){ dsnText.Append("Last-Attempt-Date: " + MIME_Utils.DateTimeToRfc2822(lastAttempt) + "\r\n"); } if(retryUntil != DateTime.MinValue){ dsnText.Append("Will-Retry-Until: " + MIME_Utils.DateTimeToRfc2822(retryUntil) + "\r\n"); } dsnText.Append("\r\n"); body_message_deliveryStatus.SetData(new MemoryStream(Encoding.UTF8.GetBytes(dsnText.ToString())),MIME_TransferEncodings.EightBit); multipartReport.BodyParts.Add(entity_message_deliveryStatus); //--- message/rfc822 if(message != null){ MIME_Entity entity_message_rfc822 = new MIME_Entity(); MIME_b_MessageRfc822 body_message_rfc822 = new MIME_b_MessageRfc822(); entity_message_rfc822.Body = body_message_rfc822; if(ret == SMTP_DSN_Ret.FullMessage){ body_message_rfc822.Message = message; } else{ MemoryStream ms = new MemoryStream(); message.Header.ToStream(ms,null,null); ms.Position = 0; body_message_rfc822.Message = Mail_Message.ParseFromStream(ms); } multipartReport.BodyParts.Add(entity_message_rfc822); } return msg; }
private Mail_Message CreateMessage(string message) { Mail_Message m = new Mail_Message(); m.MimeVersion = "1.0"; m.Date = DateTime.Now; m.MessageID = MIME_Utils.CreateMessageID(); m.From = Mail_t_MailboxList.Parse(form); m.To = Mail_t_AddressList.Parse(to); m.Subject = subject; //--- multipart/alternative ----------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); m.Body = multipartAlternative; //--- text/plain ---------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, message); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ------------------------------------------------------------------------------------------------------ MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, message); multipartAlternative.BodyParts.Add(entity_text_html); return m; }
/// <summary> /// Creates mail message. /// </summary> /// <param name="from">From: address.</param> /// <param name="to">To: address.</param> /// <param name="cc">Cc: address. Value null means not used.</param> /// <param name="bcc">bcc: address. Value null means not used.</param> /// <param name="subject">Message subject.</param> /// <param name="text">Message body text.</param> /// <param name="html">Message HTML text. Value null means not used.</param> /// <param name="attachments">Message attachments. Value null means not used.</param> /// <returns>Returns created mail message.</returns> public static Mail_Message Create(Mail_t_Mailbox from,Mail_t_Address[] to,Mail_t_Address[] cc,Mail_t_Address[] bcc,string subject,string text,string html,Mail_t_Attachment[] attachments) { // Create header. Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; if(from != null){ msg.From = new Mail_t_MailboxList(); msg.From.Add(from); } if(to != null){ msg.To = new Mail_t_AddressList(); foreach(Mail_t_Address address in to){ msg.To.Add(address); } } msg.Subject = subject; // Create message without attachments. if(attachments == null || attachments.Length == 0){ // text/plain if(string.IsNullOrEmpty(html)){ MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); msg.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,text); } // multipart/alternative // text/plain // text/html else{ MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(); msg.Body = multipartAlternative; multipartAlternative.BodyParts.Add(MIME_Entity.CreateEntity_Text_Plain(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,text)); multipartAlternative.BodyParts.Add(MIME_Entity.CreateEntity_Text_Html(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,html)); } } // Create message with attachments. else{ // multipart/mixed // text/plain // application/octet-stream if(string.IsNullOrEmpty(html)){ MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(); msg.Body = multipartMixed; multipartMixed.BodyParts.Add(MIME_Entity.CreateEntity_Text_Plain(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,text)); // Add attachments. foreach(Mail_t_Attachment attachment in attachments){ try{ multipartMixed.BodyParts.Add(MIME_Entity.CreateEntity_Attachment(attachment.Name,attachment.GetStream())); } finally{ attachment.CloseStream(); } } } // multipart/mixed // multipart/alternative // text/plain // text/html // application/octet-stream else{ MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(); msg.Body = multipartMixed; MIME_Entity entity_multipart_alternative = new MIME_Entity(); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(); entity_multipart_alternative.Body = multipartAlternative; multipartMixed.BodyParts.Add(entity_multipart_alternative); multipartAlternative.BodyParts.Add(MIME_Entity.CreateEntity_Text_Plain(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,text)); multipartAlternative.BodyParts.Add(MIME_Entity.CreateEntity_Text_Html(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,html)); // Add attachments. foreach(Mail_t_Attachment attachment in attachments){ try{ multipartMixed.BodyParts.Add(MIME_Entity.CreateEntity_Attachment(attachment.Name,attachment.GetStream())); } finally{ attachment.CloseStream(); } } } } return msg; }
/// <summary> /// Generates message missing message. /// </summary> /// <returns>Returns message missing message.</returns> public static Mail_Message GenerateMessageMissing() { Mail_Message msg = new Mail_Message(); msg.MimeVersion = "1.0"; msg.MessageID = MIME_Utils.CreateMessageID(); msg.Date = DateTime.Now; msg.From = new Mail_t_MailboxList(); msg.From.Add(new Mail_t_Mailbox("system","system")); msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox("system","system")); msg.Subject = "[MESSAGE MISSING] Message no longer exists on server !"; //--- multipart/mixed ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed); contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed); msg.Body = multipartMixed; //--- text/plain --------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Message no longer exists on server.\r\n\r\nMessage is deleted by Administrator or anti-virus software.\r\n"); multipartMixed.BodyParts.Add(entity_text_plain); return msg; }
/// <summary> /// Processes and stores message. /// </summary> /// <param name="envelopeID">Envelope ID_(MAIL FROM: ENVID).</param> /// <param name="sender">Mail from.</param> /// <param name="ret">Specifies what parts of message are returned in DSN report.</param> /// <param name="recipients">Message recipients.</param> /// <param name="msgStream">Message stream. Stream position must be there where message begins.</param> /// <param name="e">Event data.</param> /// <exception cref="ArgumentNullException">Is raised when <b>recipients</b> or <b>msgStream</b> is nulll reference.</exception> public void ProcessAndStoreMessage(string envelopeID,string sender,SMTP_DSN_Ret ret,SMTP_RcptTo[] recipients,Stream msgStream,SMTP_e_MessageStored e) { if(recipients == null){ throw new ArgumentNullException("recipients"); } if(msgStream == null){ throw new ArgumentNullException("msgStream"); } /* Message processing. *) Message filters. *) Global message rules. *) Process recipients. */ List<SMTP_RcptTo> dsn_Delivered = new List<SMTP_RcptTo>(); string[] to = new string[recipients.Length]; for(int i=0;i<to.Length;i++){ to[i] = recipients[i].Mailbox; } #region Global Filtering stuff //--- Filter message -----------------------------------------------// Stream filteredMsgStream = msgStream; DataView dvFilters = m_pApi.GetFilters(); dvFilters.RowFilter = "Enabled=true AND Type='ISmtpMessageFilter'"; dvFilters.Sort = "Cost"; foreach(DataRowView drViewFilter in dvFilters){ try{ filteredMsgStream.Position = 0; string assemblyFile = API_Utlis.PathFix(drViewFilter.Row["Assembly"].ToString()); // File is without path probably, try to load it from filters folder if(!File.Exists(assemblyFile)){ assemblyFile = API_Utlis.PathFix(m_pOwnerServer.StartupPath + "\\Filters\\" + assemblyFile); } Assembly ass = Assembly.LoadFrom(assemblyFile); Type tp = ass.GetType(drViewFilter.Row["ClassName"].ToString()); object filterInstance = Activator.CreateInstance(tp); ISmtpMessageFilter filter = (ISmtpMessageFilter)filterInstance; string errorText = ""; SMTP_Session session = null; if(e != null){ session = e.Session; } FilterResult result = filter.Filter(filteredMsgStream,out filteredMsgStream,sender,to,m_pApi,session,out errorText); if(result == FilterResult.DontStore){ // Just skip messge, act as message is stored e.Reply = new SMTP_Reply(552,"Requested mail action aborted: Message discarded by server filter."); return; } else if(result == FilterResult.Error){ if(e != null){ e.Reply = new SMTP_Reply(552,"Requested mail action aborted: " + errorText); } else{ // NOTE: 26.01.2006 - e maybe null if that method is called server internally and no smtp session. } return; } // Filter didn't return message stream if(filteredMsgStream == null){ e.Reply = new SMTP_Reply(552,"Requested mail action aborted: Message discarded by server filter."); return; } } catch(Exception x){ // Filtering failed, log error and allow message through. OnError(x); } } //---------------------------------------------------------------// #endregion #region Global Message Rules filteredMsgStream.Position = 0; Mail_Message mime = null; try{ mime = Mail_Message.ParseFromStream(filteredMsgStream); } // Invalid message syntax, block such message. catch{ e.Reply = new SMTP_Reply(552,"Requested mail action aborted: Message has invalid structure/syntax."); try{ if(!Directory.Exists(this.MailStorePath + "Unparseable")){ Directory.CreateDirectory(this.MailStorePath + "Unparseable"); } using(FileStream fs = File.Create(this.MailStorePath + "Unparseable\\" + Guid.NewGuid().ToString().Replace("-","") + ".eml")){ filteredMsgStream.Position = 0; Net_Utils.StreamCopy(filteredMsgStream,fs,32000); } } catch{ } return; } //--- Check Global Message Rules --------------------------------------------------------------// bool deleteMessage = false; string storeFolder = "Inbox"; string smtpErrorText = null; // Loop rules foreach(DataRowView drV_Rule in m_pApi.GetGlobalMessageRules()){ // Reset stream position filteredMsgStream.Position = 0; if(Convert.ToBoolean(drV_Rule["Enabled"])){ string ruleID = drV_Rule["RuleID"].ToString(); GlobalMessageRule_CheckNextRule_enum checkNextIf = (GlobalMessageRule_CheckNextRule_enum)(int)drV_Rule["CheckNextRuleIf"]; string matchExpression = drV_Rule["MatchExpression"].ToString(); // e may be null if server internal method call and no actual session ! SMTP_Session session = null; if(e != null){ session = e.Session; } GlobalMessageRuleProcessor ruleEngine = new GlobalMessageRuleProcessor(); bool matches = ruleEngine.Match(matchExpression,sender,to,session,mime,(int)filteredMsgStream.Length); if(matches){ // Do actions GlobalMessageRuleActionResult result = ruleEngine.DoActions( m_pApi.GetGlobalMessageRuleActions(ruleID), this, filteredMsgStream, sender, to ); if(result.DeleteMessage){ deleteMessage = true; } if(result.StoreFolder != null){ storeFolder = result.StoreFolder; } if(result.ErrorText != null){ smtpErrorText = result.ErrorText; } } //--- See if we must check next rule -------------------------------------------------// if(checkNextIf == GlobalMessageRule_CheckNextRule_enum.Always){ // Do nothing } else if(checkNextIf == GlobalMessageRule_CheckNextRule_enum.IfMatches && !matches){ break; } else if(checkNextIf == GlobalMessageRule_CheckNextRule_enum.IfNotMatches && matches){ break; } //------------------------------------------------------------------------------------// } } // Return error to connected client if(smtpErrorText != null){ e.Reply = new SMTP_Reply(552,"Requested mail action aborted: " + smtpErrorText); return; } // Just don't store message if(deleteMessage){ return; } // Reset stream position filteredMsgStream.Position = 0; //--- End of Global Rules -------------------------------------------------------------------// #endregion #region Process recipients HashSet<string> processedItems = new HashSet<string>(); Queue<SMTP_RcptTo> recipientsQueue = new Queue<SMTP_RcptTo>(); // Queue current recipients for processing. foreach(SMTP_RcptTo recipient in recipients){ recipientsQueue.Enqueue(recipient); } while(recipientsQueue.Count > 0){ /* Process order *) Local user *) Local address *) Local mailing list address *) Route *) Relay */ SMTP_RcptTo recipient = recipientsQueue.Dequeue(); // Check if we already have processed this item. Skip dublicate items. // This method also avoids loops when 2 recipients reference each other. if(processedItems.Contains(recipient.Mailbox)){ continue; } processedItems.Add(recipient.Mailbox); #region Local user if(recipient.Mailbox.IndexOf('@') == -1 && m_pApi.UserExists(recipient.Mailbox)){ // Add user to processed list. processedItems.Add(recipient.Mailbox); // Delivery status notification(DSN) requested to this user. if((recipient.Notify & SMTP_DSN_Notify.Success) != 0){ dsn_Delivered.Add(recipient); } ProcessUserMsg(sender,recipient.Mailbox,recipient.Mailbox,storeFolder,filteredMsgStream,e); continue; } #endregion #region Local address string localUser = m_pApi.MapUser(recipient.Mailbox); if(localUser != null){ // Add user to processed list. processedItems.Add(localUser); // Delivery status notification(DSN) requested to this user. if((recipient.Notify & SMTP_DSN_Notify.Success) != 0){ dsn_Delivered.Add(recipient); } ProcessUserMsg(sender,recipient.Mailbox,localUser,storeFolder,filteredMsgStream,e); } #endregion #region Mailing list address else if(m_pApi.MailingListExists(recipient.Mailbox)){ // Delivery status notification(DSN) requested to this user. if((recipient.Notify & SMTP_DSN_Notify.Success) != 0){ dsn_Delivered.Add(recipient); } Queue<string> processQueue = new Queue<string>(); processQueue.Enqueue(recipient.Mailbox); // Loop while there are mailing lists or nested mailing list available while(processQueue.Count > 0){ string mailingList = processQueue.Dequeue(); // Process mailing list members foreach(DataRowView drV in m_pApi.GetMailingListAddresses(mailingList)){ string member = drV["Address"].ToString(); // Member is asteric pattern matching server emails if(member.IndexOf('*') > -1){ DataView dvServerAddresses = m_pApi.GetUserAddresses(""); foreach(DataRowView drvServerAddress in dvServerAddresses){ string serverAddress = drvServerAddress["Address"].ToString(); if(SCore.IsAstericMatch(member,serverAddress)){ recipientsQueue.Enqueue(new SMTP_RcptTo(serverAddress,SMTP_DSN_Notify.NotSpecified,null)); } } } // Member is user or group, not email address else if(member.IndexOf('@') == -1){ // Member is group, replace with actual users if(m_pApi.GroupExists(member)){ foreach(string user in m_pApi.GetGroupUsers(member)){ recipientsQueue.Enqueue(new SMTP_RcptTo(user,SMTP_DSN_Notify.NotSpecified,null)); } } // Member is user else if(m_pApi.UserExists(member)){ recipientsQueue.Enqueue(new SMTP_RcptTo(member,SMTP_DSN_Notify.NotSpecified,null)); } // Unknown member, skip it. else{ } } // Member is nested mailing list else if(m_pApi.MailingListExists(member)){ processQueue.Enqueue(member); } // Member is normal email address else{ recipientsQueue.Enqueue(new SMTP_RcptTo(member,SMTP_DSN_Notify.NotSpecified,null)); } } } } #endregion else{ bool isRouted = false; #region Check Routing foreach(DataRowView drRoute in m_pApi.GetRoutes()){ // We have matching route if(Convert.ToBoolean(drRoute["Enabled"]) && SCore.IsAstericMatch(drRoute["Pattern"].ToString(),recipient.Mailbox)){ string description = drRoute["Action"].ToString(); RouteAction_enum action = (RouteAction_enum)Convert.ToInt32(drRoute["Action"]); byte[] actionData = (byte[])drRoute["ActionData"]; #region RouteToEmail if(action == RouteAction_enum.RouteToEmail){ XmlTable table = new XmlTable("ActionData"); table.Parse(actionData); // Add email to process queue. recipientsQueue.Enqueue(new SMTP_RcptTo(table.GetValue("EmailAddress"),SMTP_DSN_Notify.NotSpecified,null)); // Log if(e != null){ e.Session.LogAddText("Route '[" + description + "]: " + drRoute["Pattern"].ToString() + "' routed to email '" + table.GetValue("EmailAddress") + "'."); } } #endregion #region RouteToHost else if(action == RouteAction_enum.RouteToHost){ XmlTable table = new XmlTable("ActionData"); table.Parse(actionData); msgStream.Position = 0; // Route didn't match, so we have relay message. this.RelayServer.StoreRelayMessage( Guid.NewGuid().ToString(), envelopeID, msgStream, HostEndPoint.Parse(table.GetValue("Host") + ":" + table.GetValue("Port")), sender, recipient.Mailbox, recipient.ORCPT, recipient.Notify, ret ); // Log if(e != null){ e.Session.LogAddText("Route '[" + description + "]: " + drRoute["Pattern"].ToString() + "' routed to host '" + table.GetValue("Host") + ":" + table.GetValue("Port") + "'."); } } #endregion #region RouteToMailbox else if(action == RouteAction_enum.RouteToMailbox){ XmlTable table = new XmlTable("ActionData"); table.Parse(actionData); ProcessUserMsg(sender,recipient.Mailbox,table.GetValue("Mailbox"),storeFolder,filteredMsgStream,e); // Log if(e != null){ e.Session.LogAddText("Route '[" + description + "]: " + drRoute["Pattern"].ToString() + "' routed to user '" + table.GetValue("Mailbox") + "'."); } } #endregion isRouted = true; break; } } #endregion // Route didn't match, so we have relay message. if(!isRouted){ filteredMsgStream.Position = 0; this.RelayServer.StoreRelayMessage( Guid.NewGuid().ToString(), envelopeID, filteredMsgStream, null, sender, recipient.Mailbox, recipient.ORCPT, recipient.Notify, ret ); } } } #endregion #region DSN "delivered" // Send DSN for requested recipients. if(dsn_Delivered.Count > 0 && !string.IsNullOrEmpty(sender)){ try{ string dsn_to = ""; for(int i=0;i<dsn_Delivered.Count;i++){ if(i == (dsn_Delivered.Count - 1)){ dsn_to += dsn_Delivered[i].Mailbox; } else{ dsn_to += dsn_Delivered[i].Mailbox + "; "; } } string reportingMTA = ""; if(e != null && !string.IsNullOrEmpty(e.Session.LocalHostName)){ reportingMTA = e.Session.LocalHostName; } else{ reportingMTA = System.Net.Dns.GetHostName(); } ServerReturnMessage messageTemplate = null; if(messageTemplate == null){ string bodyRtf = "" + "{\\rtf1\\ansi\\ansicpg1257\\deff0\\deflang1061{\\fonttbl{\\f0\\froman\\fcharset0 Times New Roman;}{\\f1\froman\\fcharset186{\\*\\fname Times New Roman;}Times New Roman Baltic;}{\\f2\fswiss\\fcharset186{\\*\\fname Arial;}Arial Baltic;}}\r\n" + "{\\colortbl ;\\red0\\green128\\blue0;\\red128\\green128\\blue128;}\r\n" + "{\\*\\generator Msftedit 5.41.21.2508;}\\viewkind4\\uc1\\pard\\sb100\\sa100\\lang1033\\f0\\fs24\\par\r\n" + "Your message WAS SUCCESSFULLY DELIVERED to:\\line\\lang1061\\f1\\tab\\cf1\\lang1033\\b\\f0 " + dsn_to + "\\line\\cf0\\b0 and you explicitly requested a delivery status notification on success.\\par\\par\r\n" + "\\cf2 Your original message\\lang1061\\f1 /header\\lang1033\\f0 is attached to this e-mail\\lang1061\\f1 .\\lang1033\\f0\\par\\r\\n" + "\\cf0\\line\\par\r\n" + "\\pard\\lang1061\\f2\\fs20\\par\r\n" + "}\r\n"; messageTemplate = new ServerReturnMessage("DSN SUCCESSFULLY DELIVERED: " + mime.Subject,bodyRtf); } string rtf = messageTemplate.BodyTextRtf; Mail_Message dsnMsg = new Mail_Message(); dsnMsg.MimeVersion = "1.0"; dsnMsg.Date = DateTime.Now; dsnMsg.From = new Mail_t_MailboxList(); dsnMsg.From.Add(new Mail_t_Mailbox("Mail Delivery Subsystem","postmaster@local")); dsnMsg.To = new Mail_t_AddressList(); dsnMsg.To.Add(new Mail_t_Mailbox(null,sender)); dsnMsg.Subject = messageTemplate.Subject; //--- multipart/report ------------------------------------------------------------------------------------------------- MIME_h_ContentType contentType_multipartReport = new MIME_h_ContentType(MIME_MediaTypes.Multipart.report); contentType_multipartReport.Parameters["report-type"] = "delivery-status"; contentType_multipartReport.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartReport multipartReport = new MIME_b_MultipartReport(contentType_multipartReport); dsnMsg.Body = multipartReport; //--- multipart/alternative ----------------------------------------------------------------------------------------- MIME_Entity entity_multipart_alternative = new MIME_Entity(); MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative); contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.'); MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative); entity_multipart_alternative.Body = multipartAlternative; multipartReport.BodyParts.Add(entity_multipart_alternative); //--- text/plain --------------------------------------------------------------------------------------------------- MIME_Entity entity_text_plain = new MIME_Entity(); MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain); entity_text_plain.Body = text_plain; text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,SCore.RtfToText(rtf)); multipartAlternative.BodyParts.Add(entity_text_plain); //--- text/html ----------------------------------------------------------------------------------------------------- MIME_Entity entity_text_html = new MIME_Entity(); MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html); entity_text_html.Body = text_html; text_html.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,SCore.RtfToHtml(rtf)); multipartAlternative.BodyParts.Add(entity_text_html); //--- message/delivery-status MIME_Entity entity_message_deliveryStatus = new MIME_Entity(); MIME_b_MessageDeliveryStatus body_message_deliveryStatus = new MIME_b_MessageDeliveryStatus(); entity_message_deliveryStatus.Body = body_message_deliveryStatus; multipartReport.BodyParts.Add(entity_message_deliveryStatus); //--- per-message-fields ---------------------------------------------------------------------------- MIME_h_Collection messageFields = body_message_deliveryStatus.MessageFields; if(!string.IsNullOrEmpty(envelopeID)){ messageFields.Add(new MIME_h_Unstructured("Original-Envelope-Id",envelopeID)); } messageFields.Add(new MIME_h_Unstructured("Arrival-Date",MIME_Utils.DateTimeToRfc2822(DateTime.Now))); if(e != null && !string.IsNullOrEmpty(e.Session.EhloHost)){ messageFields.Add(new MIME_h_Unstructured("Received-From-MTA","dns;" + e.Session.EhloHost)); } messageFields.Add(new MIME_h_Unstructured("Reporting-MTA","dns;" + reportingMTA)); //--------------------------------------------------------------------------------------------------- foreach(SMTP_RcptTo r in dsn_Delivered){ //--- per-recipient-fields -------------------------------------------------------------------------- MIME_h_Collection recipientFields = new MIME_h_Collection(new MIME_h_Provider()); if(r.ORCPT != null){ recipientFields.Add(new MIME_h_Unstructured("Original-Recipient",r.ORCPT)); } recipientFields.Add(new MIME_h_Unstructured("Final-Recipient","rfc822;" + r.Mailbox)); recipientFields.Add(new MIME_h_Unstructured("Action","delivered")); recipientFields.Add(new MIME_h_Unstructured("Status","2.0.0")); body_message_deliveryStatus.RecipientBlocks.Add(recipientFields); //--------------------------------------------------------------------------------------------------- } //--- message/rfc822 if(mime != null){ MIME_Entity entity_message_rfc822 = new MIME_Entity(); MIME_b_MessageRfc822 body_message_rfc822 = new MIME_b_MessageRfc822(); entity_message_rfc822.Body = body_message_rfc822; if(ret == SMTP_DSN_Ret.FullMessage){ body_message_rfc822.Message = mime; } else{ MemoryStream ms = new MemoryStream(); mime.Header.ToStream(ms,null,null); ms.Position = 0; body_message_rfc822.Message = Mail_Message.ParseFromStream(ms); } multipartReport.BodyParts.Add(entity_message_rfc822); } using(MemoryStream strm = new MemoryStream()){ dsnMsg.ToStream(strm,new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8); ProcessAndStoreMessage("",new string[]{sender},strm,null); } } catch(Exception x){ Error.DumpError(this.Name,x); } } #endregion }