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> /// Default constructor. /// </summary> public RelayVariablesManager(RelayServer server,Relay_Session relaySession,string errorText,Mail_Message message) { m_pRelayServer = server; m_pRelaySession = relaySession; m_ErrorText = errorText; m_pMessageStream = relaySession.MessageStream; m_pMime = message; }
/// <summary> /// Constructs FETCH BODY and BODYSTRUCTURE response. /// </summary> /// <param name="message">Mail message.</param> /// <param name="bodystructure">Specifies if to construct BODY or BODYSTRUCTURE.</param> /// <returns></returns> public static string ConstructBodyStructure(Mail_Message message,bool bodystructure) { if(bodystructure){ return "BODYSTRUCTURE " + ConstructParts(message,bodystructure); } else{ return "BODY " + ConstructParts(message,bodystructure); } }
/// <summary> /// 获取邮件发送时间 /// </summary> /// <param name="mailIndex"></param> /// <returns></returns> public override DateTime GetMailSendDate(Int32 mailIndex) { LumiSoft.Net.Mail.Mail_Message mMessage = Mail_Message.ParseFromByte(_pop3MessageList[mailIndex - 1].HeaderToByte()); if (mMessage.From != null) { return(mMessage.Date); } return(DateTime.MinValue); }
/// <summary> /// 获取邮件的主题 /// </summary> /// <param name="mailIndex"></param> /// <returns></returns> public override String GetMailUid(Int32 mailIndex) { LumiSoft.Net.Mail.Mail_Message mMessage = Mail_Message.ParseFromByte(_pop3MessageList[mailIndex - 1].HeaderToByte()); if (mMessage.From != null) { return(mMessage.Subject); } return(""); }
/// <summary> /// Default constructor. /// </summary> /// <param name="msgInfo">Message info.</param> /// <param name="msgData">Message data stream.</param> /// <exception cref="ArgumentNullException">Is raised when <b>msgInfo</b> is null reference.</exception> public e_NewMessageData(IMAP_MessageInfo msgInfo,Mail_Message msgData) { if(msgInfo == null){ throw new ArgumentNullException("msgInfo"); } m_pMsgInfo = msgInfo; m_pMsgData = msgData; }
/// <summary> /// 获取邮件正文 /// </summary> /// <param name="mailIndex">邮件顺序</param> /// <returns></returns> public override String GetMailBodyAsText(Int32 mailIndex) { LumiSoft.Net.Mail.Mail_Message mMessage = Mail_Message.ParseFromByte(_pop3MessageList[mailIndex - 1].HeaderToByte()); if (mMessage.From != null) { return(mMessage.BodyText); //return MMessage.BodyHtmlText; } return(""); }
private static void CreateAttachmentPart(Mail_Message msg, List<BaseAttachment> Attachments) { if (Attachments != null) { MIME_b_MultipartMixed multipartMixed = (MIME_b_MultipartMixed)msg.Body; foreach (BaseAttachment attach in Attachments) { if (attach.AttachStream != null) { multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(attach.AttachStream, attach.FileName)); } } } }
public Mail_Message TransferMessage(BaseMailMessage 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(message.DisplayName, message.From)); msg.To = new Mail_t_AddressList(); msg.To.Add(new Mail_t_Mailbox(message.To, message.To)); msg.Subject = message.Subject; // msg.Priority = message.Priority; CreateBodyPart(msg, message.Body); CreateAttachmentPart(msg, message.Attachments); return msg; }
/// <summary> /// 获取发件人 /// </summary> /// <param name="mailIndex"></param> /// <returns></returns> public override String GetSendMialAddress(Int32 mailIndex) { if (mailIndex == 0) { return(""); } else if (mailIndex > mailTotalCount) { return(""); } LumiSoft.Net.Mail.Mail_Message MMessage = Mail_Message.ParseFromByte(pop3MessageList[mailIndex - 1].HeaderToByte()); if (MMessage.From != null) { return(MMessage.From[0].Address); } return(""); }
/// <summary> /// 获取发件人 /// </summary> /// <param name="mailIndex"></param> /// <returns></returns> public override String GetSenderName(Int32 mailIndex) { if (mailIndex == 0) { return(""); } else if (mailIndex > _mailTotalCount) { return(""); } LumiSoft.Net.Mail.Mail_Message mMessage = Mail_Message.ParseFromByte(_pop3MessageList[mailIndex - 1].HeaderToByte()); if (mMessage.From != null) { return(mMessage.From[0].DisplayName); } return(""); }
/// <summary> /// Sends message by using specified smart host. /// </summary> /// <param name="localHost">Host name which is reported to SMTP server. Value null means local computer name is used.</param> /// <param name="host">Host name or IP address.</param> /// <param name="port">Host port.</param> /// <param name="security">Specifies connection security.</param> /// <param name="userName">SMTP server user name. This value may be null, then authentication not used.</param> /// <param name="password">SMTP server password.</param> /// <param name="message">Mail message to send.</param> /// <exception cref="ArgumentNullException">Is raised when argument <b>host</b> or <b>message</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the method arguments has invalid value.</exception> /// <exception cref="SMTP_ClientException">Is raised when SMTP server returns error.</exception> public static void QuickSendSmartHost(string localHost,string host,int port,TcpClientSecurity security,string userName,string password,Mail_Message message) { QuickSendSmartHost(localHost,host,port,security == TcpClientSecurity.SSL,userName,password,message); }
/// <summary> /// Sends message by using specified smart host. /// </summary> /// <param name="host">Host name or IP address.</param> /// <param name="port">Host port.</param> /// <param name="ssl">Specifies if connected via SSL.</param> /// <param name="message">Mail message to send.</param> /// <exception cref="ArgumentNullException">Is raised when argument <b>host</b> or <b>message</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the method arguments has invalid value.</exception> /// <exception cref="SMTP_ClientException">Is raised when SMTP server returns error.</exception> public static void QuickSendSmartHost(string host,int port,bool ssl,Mail_Message message) { if(message == null){ throw new ArgumentNullException("message"); } QuickSendSmartHost(null,host,port,ssl,null,null,message); }
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; }
private string GetMessageContent(Mail_Message mailbody, Project project, out bool isContentHtml, ref List<MIME_Entity> attachments) { string content = ""; isContentHtml = false; attachments = new List<MIME_Entity>(); // parse the text content if (string.IsNullOrEmpty(mailbody.BodyHtmlText)) // no html must be text { content = mailbody.BodyText.Replace("\n\r", "<br/>").Replace("\r\n", "<br/>").Replace("\r", ""); int replyToPos = content.IndexOf("-- WRITE ABOVE THIS LINE TO REPLY --"); if (replyToPos != -1) content = content.Substring(0, replyToPos); } else { //TODO: Enhancements could include regular expressions / string matching or not matching // for particular strings values in the subject or body. // strip the <body> out of the message (using code from below) var bodyExtractor = new Regex("<body.*?>(?<content>.*)</body>", RegexOptions.IgnoreCase | RegexOptions.Singleline); var match = bodyExtractor.Match(mailbody.BodyHtmlText); var emailContent = match.Success && match.Groups["content"] != null ? match.Groups["content"].Value : mailbody.BodyHtmlText; isContentHtml = true; content = emailContent.Replace("<", "<").Replace(">", ">"); content = Regex.Replace(content, "</?o:p>", string.Empty); // Clean MSWord stuff int replyToStart = content.IndexOf("<p>-- WRITE ABOVE THIS LINE TO REPLY --</p>"); int replyToEnd = content.IndexOf("<p>-- WRITE BELOW THIS LINE TO REPLY --</p>"); if (replyToStart != -1 && replyToEnd != -1) content = content.Substring(0, replyToStart) + content.Substring(replyToEnd + 43); } // parse attachments if (Config.ProcessAttachments && project.AllowAttachments) { List<MIME_Entity> allAttachs = mailbody.GetAttachments(Config.ProcessInlineAttachedPictures).Where(p => p.ContentType != null).ToList(); // parse inline images for (int i = 0; i < allAttachs.Count; i++) { var attachment = allAttachs[i]; if (attachment.Body is MIME_b_Image && !string.IsNullOrEmpty(attachment.ContentID)) { var inlineKey = "cid:" + attachment.ContentID.Replace("<", "").Replace(">", ""); if (content.Contains(inlineKey)) { content = content.Replace(inlineKey, ConvertImageToBase64(attachment)); } else { attachments.Add(attachment); } } else { attachments.Add(attachment); } } } return content; }
private bool ProcessNewComment(List<string> recipients, POP3_ClientMessage message, Mail_Message mailHeader, MailboxReaderResult result) { string messageFrom = string.Empty; if (mailHeader.From.Count > 0) { messageFrom = string.Join("; ", mailHeader.From.ToList().Select(p => p.Address).ToArray()).Trim(); } bool processed = false; foreach (var address in recipients) { Regex isReply = new Regex(@"(.*)(\+iid-)(\d+)@(.*)"); Match commentMatch = isReply.Match(address); if (commentMatch.Success && commentMatch.Groups.Count >= 4) { // we are in a reply and group 4 must contain the id of the original issue int issueId; if (int.TryParse(commentMatch.Groups[3].Value, out issueId)) { var _currentIssue = IssueManager.GetById(issueId); if (_currentIssue != null) { var project = ProjectManager.GetById(_currentIssue.ProjectId); var mailbody = Mail_Message.ParseFromByte(message.MessageToByte()); bool isHtml; List<MIME_Entity> attachments = null; string content = GetMessageContent(mailbody, project, out isHtml, ref attachments); IssueComment comment = new IssueComment { IssueId = issueId, Comment = content, DateCreated = mailHeader.Date }; // try to find if the creator is valid user in the project, otherwise take // the user defined in the mailbox config var users = UserManager.GetUsersByProjectId(project.Id); var emails = messageFrom.Split(';').Select(e => e.Trim().ToLower()); var user = users.Find(x => emails.Contains(x.Email.ToLower())); if (user != null) { comment.CreatorUserName = user.UserName; } else { // user not found continue; } var saved = IssueCommentManager.SaveOrUpdate(comment); if (saved) { //add history record var history = new IssueHistory { IssueId = issueId, CreatedUserName = comment.CreatorUserName, DateChanged = comment.DateCreated, FieldChanged = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Comment", "Comment"), OldValue = string.Empty, NewValue = ResourceStrings.GetGlobalResource(GlobalResources.SharedResources, "Added", "Added"), TriggerLastUpdateChange = true }; IssueHistoryManager.SaveOrUpdate(history); var projectFolderPath = Path.Combine(Config.UploadsFolderPath, project.UploadPath); // save attachments as new files int attachmentsSavedCount = 1; foreach (MIME_Entity mimeEntity in attachments) { string fileName; var contentType = mimeEntity.ContentType.Type.ToLower(); var attachment = new IssueAttachment { Id = 0, Description = "File attached by mailbox reader", DateCreated = DateTime.Now, ContentType = mimeEntity.ContentType.TypeWithSubtype, CreatorDisplayName = user.DisplayName, CreatorUserName = user.UserName, IssueId = issueId, ProjectFolderPath = projectFolderPath }; attachment.Attachment = ((MIME_b_SinglepartBase)mimeEntity.Body).Data; if (contentType.Equals("attachment")) // this is an attached email { fileName = mimeEntity.ContentDisposition.Param_FileName; } else if (contentType.Equals("message")) // message has no filename so we create one { fileName = string.Format("Attached_Message_{0}.eml", attachmentsSavedCount); } else { fileName = string.IsNullOrWhiteSpace(mimeEntity.ContentType.Param_Name) ? string.Format("untitled.{0}", mimeEntity.ContentType.SubType) : mimeEntity.ContentType.Param_Name; } attachment.FileName = fileName; var saveFile = IsAllowedFileExtension(fileName); var fileSaved = false; // can we save the file? if (saveFile) { fileSaved = IssueAttachmentManager.SaveOrUpdate(attachment); if (fileSaved) { attachmentsSavedCount++; } else { LogWarning("MailboxReader: Attachment could not be saved, please see previous logs"); } } } processed = true; // add the entry if the save did not throw any exceptions result.MailboxEntries.Add(new MailboxEntry()); } } } } } return processed; }
//lumisoft smtp public void sendMailSmtp(string adressFrom, string psw, int port, string hostname, bool ssl, string stradresseRecu, string stradresseCC, string strSujet, string strbodymailhtml, int indexPriorite) { var Host = new LumiSoft.Net.SMTP.Client.SMTP_Client(); Host.Connect(hostname, port, ssl); Host.EhloHelo(hostname); Host.Auth(Host.AuthGetStrongestMethod(adressFrom, psw)); LumiSoft.Net.Mail.Mail_Message mailMsg = new LumiSoft.Net.Mail.Mail_Message(); mailMsg.MessageID = LumiSoft.Net.MIME.MIME_Utils.CreateMessageID(); string[] adresseRecu = getListAdress(stradresseRecu); string[] adressCC = getListAdress(stradresseCC); string mailSujet = strSujet; for (int i = 0; i < adresseRecu.Length; i++) { if (!string.IsNullOrEmpty(adresseRecu[i])) { mailMsg.To = new LumiSoft.Net.Mail.Mail_t_AddressList(); } mailMsg.To.Add(new LumiSoft.Net.Mail.Mail_t_Mailbox(adresseRecu[i], adresseRecu[i])); } for (int i = 0; i < adressCC.Length; i++) { if (!string.IsNullOrEmpty(adressCC[i])) { mailMsg.Cc = new LumiSoft.Net.Mail.Mail_t_AddressList(); } mailMsg.Cc.Add(new LumiSoft.Net.Mail.Mail_t_Mailbox(adressCC[i], adressCC[i])); } mailMsg.Subject = mailSujet; mailMsg.From = new LumiSoft.Net.Mail.Mail_t_MailboxList(); mailMsg.From.Add(new LumiSoft.Net.Mail.Mail_t_Mailbox(adressFrom, adressFrom)); string mailbody = HttpUtility.UrlDecode(strbodymailhtml); switch (indexPriorite) { case 0: mailMsg.Priority = "normal"; break; case 1: mailMsg.Priority = "urgent"; break; case 2: mailMsg.Priority = "non-urgent"; break; } var body = new MIME_b_Text(MIME_MediaTypes.Text.html); mailMsg.Body = body; //il faut avoir l'autorisation faute de quoi il va envoyer "Body must be bounded to some entity first" pour l'exception body.SetText(MIME_TransferEncodings.Base64, Encoding.UTF8, mailbody); if (WebUserControl1.Emaildatastatic.getInstance().getDataTable().Rows.Count > 0) { foreach (DataRow dr in WebUserControl1.Emaildatastatic.getInstance().getDataTable().Rows) { } } try { } catch (System.Net.Mail.SmtpException ex) { Console.WriteLine(ex.ToString()); } mailMsg.Dispose(); Console.WriteLine("Goodbye."); }
private static MemoryStream MessageToStream(Mail_Message msg) { MemoryStream m = new MemoryStream(); MIME_Encoding_EncodedWord ew = new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.B, Encoding.UTF8); msg.ToStream(m, ew, Encoding.UTF8, false); m.Position = 0; return m; }
private Mail convertToMail(Mail_Message mime) { Mail retVal = new Mail(); retVal.Subject = mime.Subject; retVal.From = mime.From[0].Address; retVal.Date = mime.Date; // TODO: Combine patterns if (retVal.From.EndsWith("hotmail.com")) { retVal.Body = clearMailBody(mime.BodyText, _hotmailEndPattern); retVal.BodyHtml = clearMailBodyHtml(mime.BodyHtmlText, _hotmailHtmlEnd); } else { retVal.Body = clearMailBody(mime.BodyText, _gmailEndPattern); retVal.BodyHtml = clearMailBodyHtml(mime.BodyHtmlText, _gmailHtmlEnd); } return retVal; }
/// <summary> /// Default constructor. /// </summary> public MIME_b_MessageRfc822() : base(new MIME_h_ContentType("message/rfc822")) { m_pMessage = new Mail_Message(); }
/// <summary> /// Raises <b>NewMessageData</b> event. /// </summary> /// <param name="msgInfo">IMAP message info which message data it is.</param> /// <param name="msgData">Message data. NOTE: This value must be as specified by <see cref="IMAP_e_Fetch.FetchDataType"/>.</param> private void OnNewMessageData(IMAP_MessageInfo msgInfo,Mail_Message msgData) { if(this.NewMessageData != null){ this.NewMessageData(this,new e_NewMessageData(msgInfo,msgData)); } }
/// <summary> /// Adds specified message for FETCH response processing. /// </summary> /// <param name="msgInfo">IMAP message info which message data it is.</param> /// <param name="msgData">Message data. NOTE: This value must be as specified by <see cref="IMAP_e_Fetch.FetchDataType"/>.</param> /// <exception cref="ArgumentNullException">Is raised when <b>msgInfo</b> or <b>msgData</b> is null reference.</exception> public void AddData(IMAP_MessageInfo msgInfo,Mail_Message msgData) { if(msgInfo == null){ throw new ArgumentNullException("msgInfo"); } if(msgData == null){ throw new ArgumentNullException("msgData"); } OnNewMessageData(msgInfo,msgData); }
private Mail_Message CreateTestMail(MailMessage 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(message.From.DisplayName, message.From.Address)); msg.To = new Mail_t_AddressList(); message.To.ToList().ForEach(p => msg.To.Add(new Mail_t_Mailbox(p.DisplayName, p.Address))); 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 string BodyText = "这是一份测试邮件,来自<font color=red><b>厦门至正测试程序</b></font>"; CreateBodyPart(msg, BodyText); //测试邮件不发送附件 #endregion return msg; }
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); } }
/// <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(); } }
/// <summary> /// Construct secified mime entity ENVELOPE string. /// </summary> /// <param name="entity">Mail message.</param> /// <returns></returns> public static string ConstructEnvelope(Mail_Message entity) { /* RFC 3501 7.4.2 ENVELOPE A parenthesized list that describes the envelope structure of a message. This is computed by the server by parsing the [RFC-2822] header into the component parts, defaulting various fields as necessary. The fields of the envelope structure are in the following order: date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, and message-id. The date, subject, in-reply-to, and message-id fields are strings. The from, sender, reply-to, to, cc, and bcc fields are parenthesized lists of address structures. An address structure is a parenthesized list that describes an electronic mail address. The fields of an address structure are in the following order: personal name, [SMTP] at-domain-list (source route), mailbox name, and host name. [RFC-2822] group syntax is indicated by a special form of address structure in which the host name field is NIL. If the mailbox name field is also NIL, this is an end of group marker (semi-colon in RFC 822 syntax). If the mailbox name field is non-NIL, this is a start of group marker, and the mailbox name field holds the group name phrase. If the Date, Subject, In-Reply-To, and Message-ID header lines are absent in the [RFC-2822] header, the corresponding member of the envelope is NIL; if these header lines are present but empty the corresponding member of the envelope is the empty string. Note: some servers may return a NIL envelope member in the "present but empty" case. Clients SHOULD treat NIL and empty string as identical. Note: [RFC-2822] requires that all messages have a valid Date header. Therefore, the date member in the envelope can not be NIL or the empty string. Note: [RFC-2822] requires that the In-Reply-To and Message-ID headers, if present, have non-empty content. Therefore, the in-reply-to and message-id members in the envelope can not be the empty string. If the From, To, cc, and bcc header lines are absent in the [RFC-2822] header, or are present but empty, the corresponding member of the envelope is NIL. If the Sender or Reply-To lines are absent in the [RFC-2822] header, or are present but empty, the server sets the corresponding member of the envelope to be the same value as the from member (the client is not expected to know to do this). Note: [RFC-2822] requires that all messages have a valid From header. Therefore, the from, sender, and reply-to members in the envelope can not be NIL. ENVELOPE ("date" "subject" from sender reply-to to cc bcc "in-reply-to" "messageID") */ // NOTE: all header fields and parameters must in ENCODED form !!! MIME_Encoding_EncodedWord wordEncoder = new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.B,Encoding.UTF8); wordEncoder.Split = false; StringBuilder retVal = new StringBuilder(); retVal.Append("ENVELOPE ("); // date try{ if(entity.Date != DateTime.MinValue){ retVal.Append(TextUtils.QuoteString(MIME_Utils.DateTimeToRfc2822(entity.Date))); } else{ retVal.Append("NIL"); } } catch{ retVal.Append("NIL"); } // subject if(entity.Subject != null){ //retVal.Append(" " + TextUtils.QuoteString(wordEncoder.Encode(entity.Subject))); string val = wordEncoder.Encode(entity.Subject); retVal.Append(" {" + val.Length + "}\r\n" + val); } else{ retVal.Append(" NIL"); } // from if(entity.From != null && entity.From.Count > 0){ retVal.Append(" " + ConstructAddresses(entity.From.ToArray(),wordEncoder)); } else{ retVal.Append(" NIL"); } // sender // NOTE: There is confusing part, according rfc 2822 Sender: is MailboxAddress and not AddressList. if(entity.Sender != null){ retVal.Append(" ("); retVal.Append(ConstructAddress(entity.Sender,wordEncoder)); retVal.Append(")"); } else{ retVal.Append(" NIL"); } // reply-to if(entity.ReplyTo != null){ retVal.Append(" " + ConstructAddresses(entity.ReplyTo.Mailboxes,wordEncoder)); } else{ retVal.Append(" NIL"); } // to if(entity.To != null && entity.To.Count > 0){ retVal.Append(" " + ConstructAddresses(entity.To.Mailboxes,wordEncoder)); } else{ retVal.Append(" NIL"); } // cc if(entity.Cc != null && entity.Cc.Count > 0){ retVal.Append(" " + ConstructAddresses(entity.Cc.Mailboxes,wordEncoder)); } else{ retVal.Append(" NIL"); } // bcc if(entity.Bcc != null && entity.Bcc.Count > 0){ retVal.Append(" " + ConstructAddresses(entity.Bcc.Mailboxes,wordEncoder)); } else{ retVal.Append(" NIL"); } // in-reply-to if(entity.InReplyTo != null){ retVal.Append(" " + TextUtils.QuoteString(wordEncoder.Encode(entity.InReplyTo))); } else{ retVal.Append(" NIL"); } // message-id if(entity.MessageID != null){ retVal.Append(" " + TextUtils.QuoteString(wordEncoder.Encode(entity.MessageID))); } else{ retVal.Append(" NIL"); } retVal.Append(")"); return retVal.ToString(); }
/// <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> /// Gets specified mime entity. Returns null if specified mime entity doesn't exist. /// </summary> /// <param name="message">Mail message.</param> /// <param name="partNumber">MIME part-number specifier. Nested mime entities are pointed by '.'. /// For example: 1,1.1,2.1, ... .</param> /// <returns></returns> /// <exception cref="ArgumentNullException">Is raised when <b>message</b> is null reference.</exception> public MIME_Entity GetMimeEntity(Mail_Message message,string partNumber) { if(message == null){ throw new ArgumentNullException("message"); } // For single part message there is only one entity with value 1. // Example: // header // entity -> 1 // For multipart message, entity counting starts from MainEntity.ChildEntities // Example: // header // multipart/mixed // text/plain -> 1 // application/pdf -> 2 // ... // TODO: nested rfc 822 message if(partNumber == string.Empty){ return message; } // Single part if(message.ContentType == null || message.ContentType.Type.ToLower() != "multipart"){ if(Convert.ToInt32(partNumber) == 1){ return message; } else{ return null; } } // multipart else{ MIME_Entity entity = message; string[] parts = partNumber.Split('.'); foreach(string part in parts){ int mEntryNo = Convert.ToInt32(part) - 1; // Enitites are zero base, mimeEntitySpecifier is 1 based. if(entity.Body is MIME_b_Multipart){ MIME_b_Multipart multipart = (MIME_b_Multipart)entity.Body; if(mEntryNo > -1 && mEntryNo < multipart.BodyParts.Count){ entity = multipart.BodyParts[mEntryNo]; } else{ return null; } } else{ return null; } } return entity; } }
private void SendUseLumi(DateTime dt) { Mail_Message mm = new Mail_Message(); mm.Date = dt; mm.MimeVersion = "1.0"; mm.MessageID = MIME_Utils.CreateMessageID(); mm.Subject = "sunshine"; mm.From.Add(new Mail_t_Mailbox(user, user)); mm.To.Add(new Mail_t_Mailbox(to, to)); mm.Body. }
/// <summary> /// Checks if specified message matches to specified criteria. /// </summary> /// <param name="syntaxCheckOnly">Specifies if syntax check is only done. If true no matching is done.</param> /// <param name="r">Match expression reader what contains match expression.</param> /// <param name="mailFrom">SMTP MAIL FROM: command email value.</param> /// <param name="rcptTo">SMTP RCPT TO: command email values.</param> /// <param name="smtpSession">SMTP current session.</param> /// <param name="mime">Message to match.</param> /// <param name="messageSize">Message size in bytes.</param> /// <returns>Returns true if message matches to specified criteria.</returns> private bool Match(bool syntaxCheckOnly,LumiSoft.Net.StringReader r,string mailFrom,string[] rcptTo,SMTP_Session smtpSession,Mail_Message mime,int messageSize) { /* Possible keywords order At first there can be NOT,parethesized or matcher After NOT, parethesized or matcher After matcher, AND or OR After OR, NOT,parethesized or matcher After AND, NOT,parethesized or matcher After parethesized, NOT or matcher */ PossibleClauseItem possibleClauseItems = PossibleClauseItem.Parenthesizes | PossibleClauseItem.NOT | PossibleClauseItem.Matcher; bool lastMatchValue = false; // Empty string passed r.ReadToFirstChar(); if(r.Available == 0){ throw new Exception("Invalid syntax: '" + ClauseItemsToString(possibleClauseItems) + "' expected !"); } // Parse while there are expressions or get error while(r.Available > 0){ r.ReadToFirstChar(); // Syntax check must consider that there is alwas match !!! if(syntaxCheckOnly){ lastMatchValue = true; } #region () Groupped matchers // () Groupped matchers if(r.StartsWith("(")){ lastMatchValue = Match(syntaxCheckOnly,new LumiSoft.Net.StringReader(r.ReadParenthesized()),mailFrom,rcptTo,smtpSession,mime,messageSize); possibleClauseItems = PossibleClauseItem.Parenthesizes | PossibleClauseItem.Matcher | PossibleClauseItem.NOT; } #endregion #region AND clause // AND clause else if(r.StartsWith("and",false)){ // See if AND allowed if((possibleClauseItems & PossibleClauseItem.AND) == 0){ throw new Exception("Invalid syntax: '" + ClauseItemsToString(possibleClauseItems) + "' expected !"); } // Last match value is false, no need to check next conditions if(!lastMatchValue){ return false; } // Remove AND r.ReadWord(); r.ReadToFirstChar(); lastMatchValue = Match(syntaxCheckOnly,r,mailFrom,rcptTo,smtpSession,mime,messageSize); possibleClauseItems = PossibleClauseItem.Parenthesizes | PossibleClauseItem.Matcher | PossibleClauseItem.NOT; } #endregion #region OR clause // OR clause else if(r.StartsWith("or",false)){ // See if OR allowed if((possibleClauseItems & PossibleClauseItem.OR) == 0){ throw new Exception("Invalid syntax: '" + ClauseItemsToString(possibleClauseItems) + "' expected !"); } // Remove OR r.ReadWord(); r.ReadToFirstChar(); // Last match value is false, then we need to check next condition. // Otherwise OR is matched already, just eat next matcher. if(lastMatchValue){ // Skip next clause Match(syntaxCheckOnly,r,mailFrom,rcptTo,smtpSession,mime,messageSize); } else{ lastMatchValue = Match(syntaxCheckOnly,r,mailFrom,rcptTo,smtpSession,mime,messageSize); } possibleClauseItems = PossibleClauseItem.Parenthesizes | PossibleClauseItem.Matcher | PossibleClauseItem.NOT; } #endregion #region NOT clause // NOT clause else if(r.StartsWith("not",false)){ // See if NOT allowed if((possibleClauseItems & PossibleClauseItem.NOT) == 0){ throw new Exception("Invalid syntax: '" + ClauseItemsToString(possibleClauseItems) + "' expected !"); } // Remove NOT r.ReadWord(); r.ReadToFirstChar(); // Just reverse match result value lastMatchValue = !Match(syntaxCheckOnly,r,mailFrom,rcptTo,smtpSession,mime,messageSize); possibleClauseItems = PossibleClauseItem.Parenthesizes | PossibleClauseItem.Matcher; } #endregion else{ // See if matcher allowed if((possibleClauseItems & PossibleClauseItem.Matcher) == 0){ throw new Exception("Invalid syntax: '" + ClauseItemsToString(possibleClauseItems) + "' expected ! \r\n\r\n Near: '" + r.OriginalString.Substring(0,r.Position) + "'"); } // 1) matchsource // 2) keyword // Read match source string word = r.ReadWord(); if(word == null){ throw new Exception("Invalid syntax: matcher is missing !"); } word = word.ToLower(); string[] matchSourceValues = new string[]{}; #region smtp.mail_from // SMTP command MAIL FROM: value. // smtp.mail_from if(word == "smtp.mail_from"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{mailFrom}; } } #endregion #region smtp.rcpt_to // SMTP command RCPT TO: values. // smtp.mail_to else if(word == "smtp.rcpt_to"){ if(!syntaxCheckOnly){ matchSourceValues = rcptTo; } } #endregion #region smtp.ehlo // SMTP command EHLO/HELO: value. // smtp.ehlo else if(word == "smtp.ehlo"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{smtpSession.EhloHost}; } } #endregion #region smtp.authenticated // Specifies if SMTP session is authenticated. // smtp.authenticated else if(word == "smtp.authenticated"){ if(!syntaxCheckOnly){ if(smtpSession != null){ matchSourceValues = new string[]{smtpSession.IsAuthenticated.ToString()}; } } } #endregion #region smtp.user // SMTP authenticated user name. Empy string "" if not authenticated. // smtp.user else if(word == "smtp.user"){ if(!syntaxCheckOnly){ if(smtpSession != null && smtpSession.AuthenticatedUserIdentity != null){ matchSourceValues = new string[]{smtpSession.AuthenticatedUserIdentity.Name}; } } } #endregion #region smtp.remote_ip // SMTP session connected client IP address. // smtp.remote_ip else if(word == "smtp.remote_ip"){ if(!syntaxCheckOnly){ if(smtpSession != null){ matchSourceValues = new string[]{smtpSession.RemoteEndPoint.Address.ToString()}; } } } #endregion #region message.size // Message size in bytes. // message.size else if(word == "message.size"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{messageSize.ToString()}; } } #endregion #region message.header <SP> "HeaderFieldName:" // Message main header header field. If multiple header fields, then all are checked. // message.header <SP> "HeaderFieldName:" else if(word == "message.header"){ string headerFieldName = r.ReadWord(); if(headerFieldName == null){ throw new Exception("Match source MainHeaderField HeaderFieldName is missing ! Syntax:{MainHeaderField <SP> \"HeaderFieldName:\"}"); } if(!syntaxCheckOnly){ if(mime.Header.Contains(headerFieldName)){ MIME_h[] fields = mime.Header[headerFieldName]; matchSourceValues = new string[fields.Length]; for(int i=0;i<matchSourceValues.Length;i++){ matchSourceValues[i] = fields[i].ValueToString(); } } } } #endregion #region message.all_headers <SP> "HeaderFieldName:" // Any mime entity header header field. If multiple header fields, then all are checked. // message.all_headers <SP> "HeaderFieldName:" else if(word == "message.all_headers"){ string headerFieldName = r.ReadWord(); if(headerFieldName == null){ throw new Exception("Match source MainHeaderField HeaderFieldName is missing ! Syntax:{MainHeaderField <SP> \"HeaderFieldName:\"}"); } if(!syntaxCheckOnly){ List<string> values = new List<string>(); foreach(MIME_Entity entity in mime.AllEntities){ if(entity.Header.Contains(headerFieldName)){ MIME_h[] fields = entity.Header[headerFieldName]; for(int i=0;i<fields.Length;i++){ values.Add(fields[i].ValueToString()); } } } matchSourceValues = values.ToArray(); } } #endregion #region message.body_text // Message body text. // message.body_text else if(word == "message.body_text"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{mime.BodyText}; } } #endregion #region message.body_html // Message body html. // message.body_html else if(word == "message.body_html"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{mime.BodyHtmlText}; } } #endregion #region message.content_md5 // Message any mime entity decoded data MD5 hash. // message.content_md5 else if(word == "message.content_md5"){ if(!syntaxCheckOnly){ List<string> values = new List<string>(); foreach(MIME_Entity entity in mime.AllEntities){ try{ if(entity.Body is MIME_b_SinglepartBase){ byte[] data = ((MIME_b_SinglepartBase)entity.Body).Data; if(data != null){ System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); values.Add(System.Text.Encoding.Default.GetString(md5.ComputeHash(data))); } } } catch{ // Message data parsing failed, just skip that entity md5 } } matchSourceValues = values.ToArray(); } } #endregion #region sys.date_time // System current date time. Format: yyyy.MM.dd HH:mm:ss. // sys.date_time else if(word == "sys.date_time"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss")}; } } #endregion #region sys.date // System current date. Format: yyyy.MM.dd. // sys.date else if(word == "sys.date"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{DateTime.Today.ToString("dd.MM.yyyy")}; } } #endregion #region sys.time // System current time. Format: HH:mm:ss. // sys.time else if(word == "sys.time"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{DateTime.Now.ToString("HH:mm:ss")}; } } #endregion #region sys.day_of_week // Day of week. Days: sunday,monday,tuesday,wednesday,thursday,friday,saturday. // sys.day_of_week else if(word == "sys.day_of_week"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{DateTime.Today.DayOfWeek.ToString()}; } } #endregion /* // Day of month. Format: 1 - 31. If no so much days in month, then replaced with month max days. // sys.day_of_month else if(word == "sys.day_of_month"){ } */ #region sys.day_of_year // Month of year. Format: 1 - 12. // sys.day_of_year else if(word == "sys.day_of_year"){ if(!syntaxCheckOnly){ matchSourceValues = new string[]{DateTime.Today.ToString("M")}; } } #endregion #region Unknown // Unknown else{ throw new Exception("Unknown match source '" + word + "' !"); } #endregion /* If we reach so far, then we have valid match sorce and compare value. Just do compare. */ // Reset lastMatch result lastMatchValue = false; // Read matcher word = r.ReadWord(true,new char[]{' '},true); if(word == null){ throw new Exception("Invalid syntax: operator is missing ! \r\n\r\n Near: '" + r.OriginalString.Substring(0,r.Position) + "'"); } word = word.ToLower(); #region * <SP> "astericPattern" // * <SP> "astericPattern" if(word == "*"){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(SCore.IsAstericMatch(val,matchSourceValue.ToLower())){ lastMatchValue = true; break; } } } } #endregion #region !* <SP> "astericPattern" // !* <SP> "astericPattern" else if(word == "!*"){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(SCore.IsAstericMatch(val,matchSourceValue.ToLower())){ lastMatchValue = false; break; } } } } #endregion #region == <SP> "value" // == <SP> "value" else if(word == "=="){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(val == matchSourceValue.ToLower()){ lastMatchValue = true; break; } } } } #endregion #region != <SP> "value" // != <SP> "value" else if(word == "!="){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found, then already value equals foreach(string matchSourceValue in matchSourceValues){ if(val == matchSourceValue.ToLower()){ lastMatchValue = false; break; } lastMatchValue = true; } } } #endregion #region >= <SP> "value" // >= <SP> "value" else if(word == ">="){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(matchSourceValue.ToLower().CompareTo(val) >= 0){ lastMatchValue = true; break; } } } } #endregion #region <= <SP> "value" // <= <SP> "value" else if(word == "<="){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(matchSourceValue.ToLower().CompareTo(val) <= 0){ lastMatchValue = true; break; } } } } #endregion #region > <SP> "value" // > <SP> "value" else if(word == ">"){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(matchSourceValue.ToLower().CompareTo(val) > 0){ lastMatchValue = true; break; } } } } #endregion #region < <SP> "value" // < <SP> "value" else if(word == "<"){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(matchSourceValue.ToLower().CompareTo(val) < 0){ lastMatchValue = true; break; } } } } #endregion #region regex <SP> "value" // Regex <SP> "value" else if(word == "regex"){ string val = r.ReadWord(); if(val == null){ throw new Exception("Invalid syntax: <SP> \"value\" is missing !"); } val = val.ToLower(); if(!syntaxCheckOnly){ // We check matchSourceValues when first is found foreach(string matchSourceValue in matchSourceValues){ if(Regex.IsMatch(val,matchSourceValue.ToLower())){ lastMatchValue = true; break; } } } } #endregion #region Unknown // Unknown else{ throw new Exception("Unknown keword '" + word + "' !"); } #endregion possibleClauseItems = PossibleClauseItem.AND | PossibleClauseItem.OR; } } return lastMatchValue; }
/// <summary> /// Checks if specified message matches to specified criteria. /// </summary> /// <param name="matchExpression">Match expression.</param> /// <param name="mailFrom">SMTP MAIL FROM: command email value.</param> /// <param name="rcptTo">SMTP RCPT TO: command email values.</param> /// <param name="smtpSession">SMTP current session.</param> /// <param name="mime">Message to match.</param> /// <param name="messageSize">Message size in bytes.</param> /// <returns>Returns true if message matches to specified criteria.</returns> public bool Match(string matchExpression,string mailFrom,string[] rcptTo,SMTP_Session smtpSession,Mail_Message mime,int messageSize) { LumiSoft.Net.StringReader r = new LumiSoft.Net.StringReader(matchExpression); return Match(false,r,mailFrom,rcptTo,smtpSession,mime,messageSize); }
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; }
/// <summary> /// Parses mail message from the specified stream. /// </summary> /// <param name="stream">Stream from where to parse mail message. Parsing starts from current stream position.</param> /// <param name="headerEncoding">Header reading encoding. If not sure UTF-8 is recommended.</param> /// <returns>Returns parsed mail message.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>headerEncoding</b> is null.</exception> public static new Mail_Message ParseFromStream(Stream stream,Encoding headerEncoding) { if(stream == null){ throw new ArgumentNullException("stream"); } if(headerEncoding == null){ throw new ArgumentNullException("headerEncoding"); } Mail_Message retVal = new Mail_Message(); retVal.Parse(new SmartStream(stream,false),headerEncoding,new MIME_h_ContentType("text/plain")); return retVal; }
/// <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; }
/// <summary> /// Sends message by using specified smart host. /// </summary> /// <param name="host">Host name or IP address.</param> /// <param name="port">Host port.</param> /// <param name="ssl">Specifies if connected via SSL.</param> /// <param name="message">Mail message to send.</param> /// <exception cref="ArgumentNullException">Is raised when argument <b>host</b> or <b>message</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the method arguments has invalid value.</exception> /// <exception cref="SMTP_ClientException">Is raised when SMTP server returns error.</exception> public static void QuickSendSmartHost(string host,int port,bool ssl,Mail_Message message) { if(message == null){ throw new ArgumentNullException("message"); } string from = ""; if(message.From != null && message.From.Count > 0){ from = ((Mail_t_Mailbox)message.From[0]).Address; } List<string> recipients = new List<string>(); if(message.To != null){ Mail_t_Mailbox[] addresses = message.To.Mailboxes; foreach(Mail_t_Mailbox address in addresses){ recipients.Add(address.Address); } } if(message.Cc != null){ Mail_t_Mailbox[] addresses = message.Cc.Mailboxes; foreach(Mail_t_Mailbox address in addresses){ recipients.Add(address.Address); } } if(message.Bcc != null){ Mail_t_Mailbox[] addresses = message.Bcc.Mailboxes; foreach(Mail_t_Mailbox address in addresses){ recipients.Add(address.Address); } // We must hide BCC message.Bcc.Clear(); } foreach(string recipient in recipients){ MemoryStream ms = new MemoryStream(); message.ToStream(ms,new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8); ms.Position = 0; QuickSendSmartHost(null,host,port,ssl,null,null,from,new string[]{recipient},ms); } }
private bool ProcessNewIssue(List<string> recipients, POP3_ClientMessage message, Mail_Message mailHeader, IList<Project> projects, MailboxReaderResult result) { var messageFrom = string.Empty; if (mailHeader.From.Count > 0) { messageFrom = string.Join("; ", mailHeader.From.ToList().Select(p => p.Address).ToArray()).Trim(); } bool processed = false; // loop through the mailboxes foreach (var address in recipients) { var pmbox = ProjectMailboxManager.GetByMailbox(address); // cannot find the mailbox skip the rest if (pmbox == null) { LogWarning(string.Format("MailboxReader: could not find project mailbox: {0} skipping.", address)); continue; } var project = projects.FirstOrDefault(p => p.Id == pmbox.ProjectId); if (project == null) { project = ProjectManager.GetById(pmbox.ProjectId); // project is disabled skip if (project.Disabled) { LogWarning(string.Format("MailboxReader: Project {0} - {1} is flagged as disabled skipping.", project.Id, project.Code)); continue; } projects.Add(project); } var entry = new MailboxEntry { Title = mailHeader.Subject.Trim(), From = messageFrom, ProjectMailbox = pmbox, Date = mailHeader.Date, Project = project, Content = "Email Body could not be parsed." }; var mailbody = Mail_Message.ParseFromByte(message.MessageToByte()); bool isHtml; List<MIME_Entity> attachments = null; string content = GetMessageContent(mailbody, project, out isHtml, ref attachments); entry.Content = content; entry.IsHtml = isHtml; foreach (var attachment in attachments) { entry.MailAttachments.Add(attachment); } //save this message Issue issue = SaveMailboxEntry(entry); //send notifications for the new issue SendNotifications(issue); // add the entry if the save did not throw any exceptions result.MailboxEntries.Add(entry); processed = true; } return processed; }