public static bool IsPassRequirements(TextPart part) { if (QuestsController.reference.CheckRequirements(part)) return true; return false; }
public virtual void TestSecureMimeSignAndEncrypt() { var body = new TextPart("plain") { Text = "This is some cleartext that we'll end up signing and encrypting..." }; var self = new SecureMailboxAddress("MimeKit UnitTests", "*****@*****.**", "2c29c66e281c9c515cc16a91ac87c4da988dbadf"); var message = new MimeMessage { Subject = "Test of signing and encrypting with S/MIME" }; ApplicationPkcs7Mime encrypted; message.From.Add(self); message.To.Add(self); message.Body = body; using (var ctx = CreateContext()) { message.SignAndEncrypt(ctx); Assert.IsInstanceOf <ApplicationPkcs7Mime> (message.Body, "The message body should be an application/pkcs7-mime part."); encrypted = (ApplicationPkcs7Mime)message.Body; Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match."); } using (var ctx = CreateContext()) { var decrypted = encrypted.Decrypt(ctx); // The decrypted part should be a multipart/signed Assert.IsInstanceOf <MultipartSigned> (decrypted, "Expected the decrypted part to be a multipart/signed."); var signed = (MultipartSigned)decrypted; Assert.IsInstanceOf <TextPart> (signed[0], "Expected the first part of the multipart/signed to be a multipart."); Assert.IsInstanceOf <ApplicationPkcs7Signature> (signed[1], "Expected second part of the multipart/signed to be a pkcs7-signature."); var extracted = (TextPart)signed[0]; Assert.AreEqual(body.Text, extracted.Text, "The decrypted text part's text does not match the original."); var signatures = signed.Verify(ctx); Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify(); Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms; int i = 0; Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[i++], "Expected AES-256 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[i++], "Expected AES-192 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[i++], "Expected AES-128 capability"); if (ctx.IsEnabled(EncryptionAlgorithm.Idea)) { Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[i++], "Expected IDEA capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Cast5)) { Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[i++], "Expected Cast5 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia256)) { Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[i++], "Expected Camellia-256 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia192)) { Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[i++], "Expected Camellia-192 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia128)) { Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[i++], "Expected Camellia-128 capability"); } Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[i++], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[i++], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[i++], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[i++], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[i++], "Expected RC2-40 capability"); } } }
public virtual void TestSecureMimeEncapsulatedSigning() { var self = new MailboxAddress("MimeKit UnitTests", "*****@*****.**"); var cleartext = new TextPart("plain"); cleartext.Text = "This is some text that we'll end up signing..."; using (var ctx = CreateContext()) { var signed = ApplicationPkcs7Mime.Sign(ctx, self, DigestAlgorithm.Sha1, cleartext); MimeEntity extracted; Assert.AreEqual(SecureMimeType.SignedData, signed.SecureMimeType, "S/MIME type did not match."); var signatures = signed.Verify(ctx, out extracted); Assert.IsInstanceOf <TextPart> (extracted, "Extracted part is not the expected type."); Assert.AreEqual(cleartext.Text, ((TextPart)extracted).Text, "Extracted content is not the same as the original."); Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify(); Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms; int i = 0; Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[i++], "Expected AES-256 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[i++], "Expected AES-192 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[i++], "Expected AES-128 capability"); if (ctx.IsEnabled(EncryptionAlgorithm.Idea)) { Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[i++], "Expected IDEA capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Cast5)) { Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[i++], "Expected Cast5 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia256)) { Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[i++], "Expected Camellia-256 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia192)) { Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[i++], "Expected Camellia-192 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia128)) { Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[i++], "Expected Camellia-128 capability"); } Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[i++], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[i++], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[i++], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[i++], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[i++], "Expected RC2-40 capability"); } } }
public ActionResult EnviarEmail(Email model, string[] taginputcc, HttpPostedFileBase[] files) { /* * string pathServer = Server.MapPath("~/App_Data/CotizacionesProject-77144679de36.p12"); * X509Certificate2 cert = new X509Certificate2(pathServer, "notasecret", X509KeyStorageFlags.Exportable); * var credential = new ServiceAccountCredential(new ServiceAccountCredential * .Initializer("*****@*****.**") * { * // Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes * Scopes = new[] { "https://mail.google.com/", "https://www.googleapis.com/auth/userinfo.profile" }, * User = model.EmailDesde * }.FromCertificate(cert));*/ //Recibo la lista de emails CC List <string> emailscc = taginputcc[0].Split(',').ToList <string>(); if (taginputcc.Length > 1) { //es mayor a 1 cuando se envia email masivo emailscc = taginputcc.ToList(); } string nombreCaperta = ""; Cotizacion cotizacion = null; Tienda tienda = db.Tienda.Where(e => e.Id == model.IdTienda).FirstOrDefault(); nombreCaperta = "PDFEmpresas"; cotizacion = tienda.Cotizaciones.Where(c => c.Id == model.IdDocumento).FirstOrDefault(); string fullPathDocumento = null; if (model.NombreDocumento != null && model.NombreDocumento != "") { fullPathDocumento = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/img/" + nombreCaperta + "/" + tienda.Id), model.NombreDocumento); } bool emailEnviadoCorrectamente = false; FileStream stmcheck2Documento = null; try { using (var client = new MailKit.Net.Smtp.SmtpClient()) { var message = new MimeMessage(); message.From.Add(new MailboxAddress(model.EmailDesde, model.EmailDesde)); bool destinatariosValidos = false; if (model.EmailPara != "" && model.EmailPara != null) { message.To.Add(new MailboxAddress(model.NombreDestinatario, model.EmailPara)); destinatariosValidos = true; } string ccsString = ""; //**** Agregar emails a CC **** if (!emailscc[0].Equals("")) { ccsString += " CCs: "; foreach (var cc in emailscc) { ccsString += cc + ";"; message.Cc.Add(new MailboxAddress(cc, cc)); destinatariosValidos = true; } } if (destinatariosValidos == false) { TempData["msgEmail"] = "Error: No se ingresaron destinatarios válidos."; return(RedirectToAction("ResultadoMail", new { msgTest = "a" })); } message.Subject = model.Tema; String mensaje = HttpUtility.HtmlDecode(model.Mensaje); //mensaje = ContenidoEmail.PrepararMensajeAGuardarOEnviar(mensaje); var body = new TextPart("html") { Text = mensaje }; //---------- var multipart = new Multipart("mixed"); multipart.Add(body); //********DOCUMENTO************* if (fullPathDocumento != null) { try { stmcheck2Documento = System.IO.File.OpenRead(fullPathDocumento); } catch (Exception ex) { string m = ex.Message; } var attachmentCotizacion = new MimePart("file", "pdf"); try { attachmentCotizacion.Content = new MimeContent(stmcheck2Documento, ContentEncoding.Default); attachmentCotizacion.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment); attachmentCotizacion.ContentTransferEncoding = ContentEncoding.Base64; attachmentCotizacion.FileName = Path.GetFileName(fullPathDocumento); multipart.Add(attachmentCotizacion); } catch { //logging as needed } } if (files != null) { foreach (HttpPostedFileBase file in files) { if (file == null) { continue; } MimePart attachment = new MimePart(file.ContentType); attachment.Content = new MimeContent(file.InputStream, ContentEncoding.Default); attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment); attachment.ContentTransferEncoding = ContentEncoding.Base64; attachment.FileName = file.FileName; multipart.Add(attachment); } } message.Body = multipart; try { client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls); client.Timeout = 12000; } catch (Exception e) { TempData["msgEmail"] = "Se encontraron problemas de conexión. Por favor, revisar su conexión a internet."; return(RedirectToAction("ResultadoMail", new { msgTest = "4" })); //ViewBag.Message = "El no se ha podido enviar. Por favor, revisar su conexión a internet"; } try { var oauth2 = new SaslMechanismOAuth2(model.EmailDesde, model.Token); client.Authenticate(oauth2); } catch (Exception e) { return(RedirectToAction("ErrorSeguridad", "Email")); } try { client.Send(message); client.Disconnect(true); client.Dispose(); } catch (Exception e) { TempData["msgEmail"] = "Aviso: No se pudo comprobar si se envió el email correctamente. " + "<br />Causa probable es tamaño de los archivos y el tiempo que tomó enviarlos. " + "<br />Por favor comprobar envío en su correo electrónico." + "<br />No se generará un registro de envío en el sistema. Puede crear uno manual de ser necesario."; return(RedirectToAction("ResultadoMail", new { msgTest = "3" })); } //Thread.Sleep(5000); //----------REGISTRO MAIL-------- //RegistroEnvio regEnvio = new RegistroEnvio(plantillaemail, true, "EMAIL", // model.EmailDesde, model.EmailPara + ccsString, catalogo, ""); //regEnvio.TerminarAsociacionRegistro(db, cotizacion); emailEnviadoCorrectamente = true; } } catch (Exception e) { TempData["msgEmail"] = "Error manejando la solicitud: Un problema de conexión a Internet ha impedido enviar el Email, por favor, intente nuevamente."; return(RedirectToAction("ResultadoMail", new { msgTest = "3" })); } if (stmcheck2Documento != null) { stmcheck2Documento.Close(); } //se eliminan los archivos enviados var basePath = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/img/" + nombreCaperta + "/"), tienda.Id.ToString()); if (Directory.Exists(basePath)) { string[] fileNames = Directory.GetFiles(basePath); foreach (string fileName in fileNames) { if (fileName == fullPathDocumento) { System.IO.File.Delete(fileName); } } } //Asegurar mantener login abierto Usuario usuario = db.Usuarios.Where(u => u.Id == model.IdUsuario).FirstOrDefault(); if (usuario != null && Session["Id"] == null) { Session["Id"] = usuario.Id; Session["Nombre"] = usuario.NombreUsuario; Session["Rol"] = usuario.RolUsuario; Session["EmpresaId"] = tienda.Id; //FuncionesGlobalesControllers.RefreshSession(this, empresa, user); } if (emailEnviadoCorrectamente) { //ReporteErrores.CrearReporteError(db, // "Email enviado correctamente. user: "******" empresa: " + empresa.Nombre ); TempData["msgEmail"] = "Email enviado correctamente"; return(RedirectToAction("ResultadoMail", new { msgTest = "2" })); } else { TempData["msgEmail"] = "Error manejando la solicitud: Un problema de conexión a Internet ha impedido enviar el Email, por favor, intente nuevamente."; return(RedirectToAction("ResultadoMail", new { msgTest = "1" })); } }
private MimeMessage BuildMailMessage(NotifyMessage m) { var mimeMessage = new MimeMessage { Subject = m.Subject }; var fromAddress = MailboxAddress.Parse(ParserOptions.Default, m.From); mimeMessage.From.Add(fromAddress); foreach (var to in m.To.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)) { mimeMessage.To.Add(MailboxAddress.Parse(ParserOptions.Default, to)); } if (m.ContentType == Pattern.HTMLContentType) { var textPart = new TextPart("plain") { Text = HtmlUtil.GetText(m.Content), ContentTransferEncoding = ContentEncoding.QuotedPrintable }; var multipartAlternative = new MultipartAlternative { textPart }; var htmlPart = new TextPart("html") { Text = GetHtmlView(m.Content), ContentTransferEncoding = ContentEncoding.QuotedPrintable }; if (m.EmbeddedAttachments != null && m.EmbeddedAttachments.Length > 0) { var multipartRelated = new MultipartRelated { Root = htmlPart }; foreach (var attachment in m.EmbeddedAttachments) { var mimeEntity = ConvertAttachmentToMimePart(attachment); if (mimeEntity != null) { multipartRelated.Add(mimeEntity); } } multipartAlternative.Add(multipartRelated); } else { multipartAlternative.Add(htmlPart); } mimeMessage.Body = multipartAlternative; } else { mimeMessage.Body = new TextPart("plain") { Text = m.Content, ContentTransferEncoding = ContentEncoding.QuotedPrintable }; } if (!string.IsNullOrEmpty(m.ReplyTo)) { mimeMessage.ReplyTo.Add(MailboxAddress.Parse(ParserOptions.Default, m.ReplyTo)); } mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); return(mimeMessage); }
/// <summary> /// /// </summary> /// <param name="toAddresss"></param> /// <param name="title"></param> /// <param name="content"></param> /// <param name="msgPath"></param> /// <returns></returns> private async Task <int> SendToEmailAsync(List <string> toAddresss, string title, string content, string html, string msgPath = "") { //实例化需要发送的资源的消息 MimeMessage message = new MimeMessage(); //发件人的地址 message.From.Add(new MailboxAddress(emailOptions.Value.EmailAddress)); toAddresss.ForEach((item) => { //收件人的地址 message.To.Add(new MailboxAddress(item)); }); //标题 message.Subject = title; //初始化mime的新的实例内容(邮件的内容) var multipart = new Multipart(); //文本内容 if (!string.IsNullOrWhiteSpace(content)) { var text = new TextPart(TextFormat.Text) { Text = content }; multipart.Add(text); } //html内容 if (!string.IsNullOrWhiteSpace(html)) { var htmlContent = new TextPart(TextFormat.Html) { Text = html }; multipart.Add(htmlContent); } //附件 if (!string.IsNullOrWhiteSpace(msgPath)) { var paths = msgPath.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (paths != null && paths.Length > 0) { foreach (var item in paths) { //验证文件是否存在 if (!File.Exists(item)) { logger.LogInformation($"邮箱发送-附件添加失败-找不到文件地址:{item}"); continue; } var attMime = new MimePart() { FileName = Path.GetFileName(item), //文件名 ContentTransferEncoding = ContentEncoding.Base64, //编码 ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), //附件 IsAttachment = true, Content = new MimeContent(File.OpenRead(item), ContentEncoding.Default) }; multipart.Add(attMime); } } } //内容 message.Body = multipart; //发件 日期 message.Date = DateTimeOffset.Now; try { //实例化 smtp 服务器 using (SmtpClient smtpClient = new SmtpClient()) { //连接到邮箱的服务器 启用ssl await smtpClient.ConnectAsync(emailOptions.Value.EmailHost, emailOptions.Value.EmailPort, false); //邮箱认证 await smtpClient.AuthenticateAsync(new NetworkCredential(emailOptions.Value.EmailAddress, emailOptions.Value.EmailCode)); //发送邮件 await smtpClient.SendAsync(message); //断开服务连接 await smtpClient.DisconnectAsync(true); return(1); } } catch (Exception ex) { logger.LogInformation($"邮箱发送错误:{ex.Message}"); return(0); } }
public abstract T VisitTextPart(TextPart part, T state);
void Render(MimeEntity entity) { var related = entity as MultipartRelated; if (related != null) { if (related.Root != null) { Render(related); } return; } var multipart = entity as Multipart; TextPart text; if (multipart != null) { if (multipart.ContentType.Matches("multipart", "alternative")) { // A multipart/alternative is just a collection of alternate views. // The last part is the part that most closely matches what the // user saw in his or her email client's WYSIWYG editor. TextPart preferred = null; for (int i = multipart.Count; i > 0; i--) { related = multipart[i - 1] as MultipartRelated; if (related != null) { var root = related.Root; if (root != null && root.ContentType.Matches("text", "html")) { Render(related); return; } continue; } text = multipart[i - 1] as TextPart; if (text == null) { continue; } if (text.ContentType.Matches("text", "html")) { preferred = text; break; } if (preferred == null) { preferred = text; } } if (preferred != null) { Render(preferred); } } else if (multipart.Count > 0) { // The main message body is usually the first part of a multipart/mixed. Render(multipart[0]); } return; } text = entity as TextPart; if (text != null) { Render(text); } }
/// <summary> /// /// </summary> /// <param name="mailTo"></param> /// <param name="mailCc"></param> /// <param name="mailBcc"></param> /// <param name="subject"></param> /// <param name="message"></param> /// <param name="encoding"></param> /// <param name="isHtml"></param> private void SendEmail(string mailTo, string mailCc, string mailBcc, string subject, string message, Encoding encoding, bool isHtml) { var _to = new string[0]; var _cc = new string[0]; var _bcc = new string[0]; if (!string.IsNullOrEmpty(mailTo)) { _to = mailTo.Split(',').Select(x => x.Trim()).ToArray(); } if (!string.IsNullOrEmpty(mailCc)) { _cc = mailCc.Split(',').Select(x => x.Trim()).ToArray(); } if (!string.IsNullOrEmpty(mailBcc)) { _bcc = mailBcc.Split(',').Select(x => x.Trim()).ToArray(); } var mimeMessage = new MimeMessage(); //add mail from mimeMessage.From.Add(new MailboxAddress("", SmtpOptions.User)); //add mail to foreach (var to in _to) { mimeMessage.To.Add(MailboxAddress.Parse(to)); } //add mail cc foreach (var cc in _cc) { mimeMessage.Cc.Add(MailboxAddress.Parse(cc)); } //add mail bcc foreach (var bcc in _bcc) { mimeMessage.Bcc.Add(MailboxAddress.Parse(bcc)); } //add subject mimeMessage.Subject = subject; //add email body TextPart body = null; if (isHtml) { body = new TextPart(TextFormat.Html); } else { body = new TextPart(TextFormat.Text); } //set email encoding body.SetText(encoding, message); //set email body mimeMessage.Body = body; using (var client = SmtpOptions.SmtpClient) { try { client?.Send(mimeMessage); } catch (Exception ex) { Logger.ErrorException("SmtpClient.SendEmail", ex); } finally { client?.Disconnect(true); } } }
public static void ExtractMainParts(this MailMessageData mail, MimeMessage message) { var htmlStream = new MemoryStream(); var textStream = new MemoryStream(); Action <MimeEntity> loadRealAttachment = (part) => { if ((part.ContentDisposition != null && !string.IsNullOrEmpty(part.ContentDisposition.FileName)) || part.ContentType != null && !string.IsNullOrEmpty(part.ContentType.Name)) { mail.LoadAttachments(new List <MimeEntity> { part }); } }; Action <MimePart> setBodyOrAttachment = (part) => { var entity = part as TextPart; if (htmlStream == null || textStream == null) { throw new Exception("Streams are not initialized"); } if ((entity == null || htmlStream.Length != 0 && entity.IsHtml || textStream.Length != 0 && !entity.IsHtml)) { loadRealAttachment(part); } else { if (mail.Introduction.Length < 200 && (!entity.IsHtml && !string.IsNullOrEmpty(entity.Text))) { if (string.IsNullOrEmpty(mail.Introduction)) { mail.Introduction = (entity.Text.Length > 200 ? entity.Text.Substring(0, 200) : entity.Text); } else { var need = 200 - mail.Introduction.Length; mail.Introduction += (entity.Text.Length > need ? entity.Text.Substring(0, need) : entity.Text); } mail.Introduction = mail.Introduction.Replace("\r\n", " ").Replace("\n", " ").Trim(); } var body = ConvertToHtml(entity); if (entity.IsHtml) { using (var sw = new StreamWriter(htmlStream, Encoding.UTF8, 1024, true)) { sw.Write(body); sw.Flush(); htmlStream.Seek(0, SeekOrigin.Begin); } } else { using (var sw = new StreamWriter(textStream, Encoding.UTF8, 1024, true)) { sw.Write(body); sw.Flush(); textStream.Seek(0, SeekOrigin.Begin); } } } }; var newPathIndex = ""; using (var sw = new StreamWriter(mail.HtmlBodyStream, Encoding.UTF8, 1024, true)) { using (var iter = new MimeIterator(message)) { while (string.IsNullOrEmpty(newPathIndex) ? iter.MoveNext() : iter.MoveTo(newPathIndex)) { if (!string.IsNullOrEmpty(newPathIndex)) { newPathIndex = ""; } var multipart = iter.Parent as Multipart; var part = iter.Current as MimePart; var subMessage = iter.Current as MessagePart; if (subMessage != null) { if ((subMessage.ContentDisposition != null && !string.IsNullOrEmpty(subMessage.ContentDisposition.FileName)) || subMessage.ContentType != null && !string.IsNullOrEmpty(subMessage.ContentType.Name)) { mail.LoadAttachments(new List <MimeEntity> { subMessage }, true); } else { subMessage.ContentDisposition = new ContentDisposition { Disposition = ContentDisposition.Attachment, FileName = "message.eml" }; mail.LoadAttachments(new List <MimeEntity> { subMessage }, true); } float pathIndex; if (float.TryParse(iter.PathSpecifier, out pathIndex)) { pathIndex++; newPathIndex = ((int)pathIndex).ToString(); continue; } } if (part == null || iter.Parent is MessagePart) { continue; } if (part.IsAttachment) { if (part is TnefPart) { var tnefPart = iter.Current as TnefPart; if (tnefPart != null) { mail.LoadAttachments(tnefPart.ExtractAttachments(), true); } } else { mail.LoadAttachments(new List <MimeEntity> { part }, multipart == null || !multipart.ContentType.MimeType.ToLowerInvariant().Equals("multipart/related")); } } else if (multipart != null) { switch (multipart.ContentType.MimeType.ToLowerInvariant()) { case "multipart/report": if (part is TextPart) { var entity = part as TextPart; if (entity == null) { entity = new TextPart(TextFormat.Plain); entity.SetText(Encoding.UTF8, part.ToString()); } var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else if (part is MessageDeliveryStatus) { var entity = new TextPart(TextFormat.Plain); var mds = (MessageDeliveryStatus)part; using (var memory = new MemoryStream()) { mds.Content.DecodeTo(memory); var text = Encoding.ASCII.GetString(memory.GetBuffer(), 0, (int)memory.Length) .Replace("\r\n", "\n"); entity.SetText(Encoding.UTF8, text); } var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else { loadRealAttachment(part); } break; case "multipart/mixed": if (part is TextPart) { var entity = part as TextPart; var body = ConvertToHtml(entity); if (mail.HtmlBodyStream.Length == 0) { sw.Write(body); } else { sw.Write("<hr /><br/>"); sw.Write(body); } sw.Flush(); } else { if (part.ContentType != null && part.ContentType.MediaType.Equals("image", StringComparison.InvariantCultureIgnoreCase) && part.ContentDisposition != null && part.ContentDisposition.Disposition.Equals(ContentDisposition.Inline, StringComparison.InvariantCultureIgnoreCase)) { if (string.IsNullOrEmpty(part.ContentId)) { part.ContentId = Guid.NewGuid().ToString("N").ToLower(); } mail.LoadAttachments(new List <MimeEntity> { part }); sw.Write("<hr /><br/>"); sw.Write("<img src=\"cid:{0}\">", part.ContentId); sw.Flush(); } else { loadRealAttachment(part); } } break; case "multipart/alternative": if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } break; case "multipart/related": if (part is TextPart) { setBodyOrAttachment(part); } else if (!string.IsNullOrEmpty(part.ContentId) || part.ContentLocation != null) { mail.LoadAttachments(new List <MimeEntity> { part }); } else { loadRealAttachment(part); } break; default: if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } break; } } else { if (part is TextPart) { setBodyOrAttachment(part); } else { loadRealAttachment(part); } } } } if (htmlStream.Length != 0) { if (mail.HtmlBodyStream.Length > 0) { sw.Write("<hr /><br/>"); sw.Flush(); } htmlStream.CopyTo(sw.BaseStream); } else if (textStream.Length != 0) { if (mail.HtmlBodyStream.Length == 0) { mail.TextBodyOnly = true; } else { sw.Write("<hr /><br/>"); sw.Flush(); } textStream.CopyTo(sw.BaseStream); } htmlStream.Dispose(); textStream.Dispose(); } if (mail.HtmlBodyStream.Length != 0) { return; } mail.HtmlBody = "<body><pre> </pre></body>"; mail.Introduction = ""; mail.TextBodyOnly = true; }
public void TestSecureMimeSignAndEncrypt() { var self = new MailboxAddress("MimeKit UnitTests", "*****@*****.**"); var recipients = new List <MailboxAddress> (); // encrypt to ourselves... recipients.Add(self); var cleartext = new TextPart("plain"); cleartext.Text = "This is some cleartext that we'll end up encrypting..."; ApplicationPkcs7Mime encrypted; using (var ctx = CreateContext()) { encrypted = ApplicationPkcs7Mime.SignAndEncrypt(ctx, self, DigestAlgorithm.Sha1, recipients, cleartext); Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match."); } using (var ctx = CreateContext()) { var decrypted = encrypted.Decrypt(ctx); // The decrypted part should be a multipart/signed Assert.IsInstanceOfType(typeof(MultipartSigned), decrypted, "Expected the decrypted part to be a multipart/signed."); var signed = (MultipartSigned)decrypted; Assert.IsInstanceOfType(typeof(TextPart), signed[0], "Expected the first part of the multipart/signed to be a multipart."); Assert.IsInstanceOfType(typeof(ApplicationPkcs7Signature), signed[1], "Expected second part of the multipart/signed to be a pkcs7-signature."); var extracted = (TextPart)signed[0]; Assert.AreEqual(cleartext.Text, extracted.Text, "The decrypted text part's text does not match the original."); var signatures = signed.Verify(ctx); Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify(); Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms; Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[0], "Expected Camellia-256 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[1], "Expected AES-256 capability"); Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[2], "Expected Camellia-192 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[3], "Expected AES-192 capability"); Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[4], "Expected Camellia-128 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[5], "Expected AES-128 capability"); Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[6], "Expected IDEA capability"); Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[7], "Expected Cast5 capability"); Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[8], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[9], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[10], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[11], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[11], "Expected RC2-40 capability"); } } }
void DrawPart( FastBitmap fastBmp, Font font, ref int x, int y, TextPart part ) { string text = part.Text; FastColour textCol = part.TextColour; float point = font.Size; int xMul = font.Style == FontStyle.Italic ? 1 : 0; int originX = x; foreach( char c in text ) { int coords = ConvertToCP437( c ); int srcX = (coords & 0x0F) * boxSize; int srcY = (coords >> 4) * boxSize; int srcWidth = widths[coords], dstWidth = PtToPx( point, srcWidth ); int srcHeight = boxSize, dstHeight = PtToPx( point, srcHeight ); for( int yy = 0; yy < dstHeight; yy++ ) { int fontY = srcY + yy * srcHeight / dstHeight; int* fontRow = fontPixels.GetRowPtr( fontY ); int* dstRow = fastBmp.GetRowPtr( y + yy ); int xOffset = xMul * ((dstHeight - 1 - yy) / italicSize); for( int xx = 0; xx < dstWidth; xx++ ) { int fontX = srcX + xx * srcWidth / dstWidth; int pixel = fontRow[fontX]; if( (byte)(pixel >> 24) == 0 ) continue; int col = pixel & ~0xFFFFFF; col |= ((pixel & 0xFF) * textCol.B / 255); col |= (((pixel >> 8) & 0xFF) * textCol.G / 255) << 8; col |= (((pixel >> 16) & 0xFF) * textCol.R / 255) << 16; dstRow[x + xx + xOffset] = col; } } x += PtToPx( point, srcWidth + 1 ); } }
public TextPart[] DecodeColors(string s, int defaultcolor, IntRef retLength) { TextPart[] parts = new TextPart[256]; int partsCount = 0; int currentcolor = defaultcolor; int[] currenttext = new int[256]; int currenttextLength = 0; IntRef sLength = new IntRef(); int[] sChars = platform.StringToCharArray(s, sLength); for (int i = 0; i < sLength.value; i++) { // If a & is found, try to parse a color code if (sChars[i] == '&') { //check if there's a character after it if (i + 1 < sLength.value) { //try to parse the color code int color = HexToInt(sChars[i + 1]); if (color != -1) { //Color has been parsed successfully if (currenttextLength != 0) { //Add content so far to return value TextPart part = new TextPart(); part.text = platform.CharArrayToString(currenttext, currenttextLength); part.color = currentcolor; parts[partsCount++] = part; } //Update current color and reset stored text for (int k = 0; k < currenttextLength; k++) { currenttext[k] = 0; } currenttextLength = 0; currentcolor = GetColor(color); //Increment i to prevent the code from being read again i++; } else { //no valid color code found. display as normal character currenttext[currenttextLength++] = sChars[i]; } } else { //if not, just display it as normal character currenttext[currenttextLength++] = sChars[i]; } } else { //Nothing special. Just add the current character currenttext[currenttextLength++] = s[i]; } } //Add any leftover text parts in current color if (currenttextLength != 0) { TextPart part = new TextPart(); part.text = platform.CharArrayToString(currenttext, currenttextLength); part.color = currentcolor; parts[partsCount++] = part; } retLength.value = partsCount; return parts; }
/// <summary> /// Constructor /// </summary> /// <param name="part"></param> /// <param name="location">The initialLocation of the text chunk in the display</param> public TextChunk(TextPart part, Point location) { Text = part; Location = location; Size = GuiUtils.MeasureDisplayedString(Text.Text, Text.Font); }
// public string content = @"guigudejub 您好, //此邮件由系统根据您找回密码的申请自动发出,请勿回复。 //以下为您的"临时密码": //"6222c70a " //请您打开官网后或点击这里使用临时密码进行登录,成功登录后请按照提示更换您的新密码。 //请注意: 新密码须由8-10个字母或数字组成(A-Z, a-z, 0-9),密码区分字母大小写,不可包含空格。 //如找回密码非您本人操作,或有其他任何问题,请立即通过以下方式联系我们。 //全天候客服:在线客服 //微信客服:w88cs1 //客服热线:008602180245688 //电子邮箱:cncs @w88yd.com //请收藏我们的备用域名w88.net & w88cc.cc,方便您随时访问娱乐。 //此为隐私文件,受相关法律保护。如果您并非此邮件的预期接收者,请不要阅读、使用或者散播任何和此邮件相关的信息,并立即且彻底地删除此邮件(及任何相关的拷贝)。 //我们建议您永久自己保存密码。请不要将您的个人密码告诉任何人,包括我们的员工。作为官方,我们也不会通过邮件来询问您的个人密码。 //仅有在您本人登录我们的网站时才会使用到您的密码。" public static void SendMail(int Username, string EmailAddress, string TmpPwd, string smtpSrv, int smtpPort, string FromAddress, string FromPwd) { try { var message = new MimeMessage(); message.From.Add(new MailboxAddress(FromAddress)); message.To.Add(new MailboxAddress(EmailAddress)); message.Subject = "[" + Username + "]-忘记密码"; //var plain = new MimeKit.TextPart("plain") //{ // Text = @"不好意思,我在测试程序,Sorry!" //}; string text = String.Format(@"{0} 您好,<br>此邮件由系统根据您找回密码的申请自动发出,请勿回复。<br> 以下为您的临时密码: {1}<br>请您打开官网后或点击这里使用临时密码进行登录,成功登录后请按照提示更换您的新密码。 ", Username, TmpPwd); var html = new TextPart("html") { Text = text }; // create an image attachment for the file located at path //var path = "D:\\雄安.jpg"; //var fs = File.OpenRead(path); //var attachment = new MimeKit.MimePart("image", "jpeg") //{ // ContentObject = new MimeKit.ContentObject(fs, MimeKit.ContentEncoding.Default), // ContentDisposition = new MimeKit.ContentDisposition(MimeKit.ContentDisposition.Attachment), // ContentTransferEncoding = MimeKit.ContentEncoding.Base64, // FileName = Path.GetFileName(path) //}; var alternative = new Multipart("alternative") { //alternative.Add(plain); html }; // now create the multipart/mixed container to hold the message text and the // image attachment var multipart = new Multipart("mixed") { alternative }; //multipart.Add(attachment); message.Body = multipart; using (var client = new MailKit.Net.Smtp.SmtpClient()) { // client.QueryCapabilitiesAfterAuthenticating = false; client.Connect(smtpSrv, smtpPort, true); // Note: since we don't have an OAuth2 token, disable // the XOAUTH2 authentication mechanism. client.AuthenticationMechanisms.Remove("XOAUTH2"); // Note: only needed if the SMTP server requires authentication //var mailFromAccount = FromAddress; //var mailPassword = FromPwd; client.Authenticate(FromAddress, FromPwd); client.Send(message); client.Disconnect(true); } } catch (Exception ex) { throw ex; } //fs.Dispose(); }
/// <summary> /// 发送电子邮件 /// </summary> /// <param name="subject">邮件主题</param> /// <param name="content">邮件内容主题</param> /// <param name="fromAddress">发送方信息</param> /// <param name="toAddress">接收方信息</param> /// <param name="textFormat">内容主题模式,默认TextFormat.Text</param> /// <param name="attachments">附件</param> /// <param name="ccAddress">抄送方信息</param> /// <param name="bccAddress">密送方信息</param> /// <param name="dispose">是否自动释放附件所用Stream</param> /// <returns></returns> public async Task SendEMailAsync(string subject, string content, IEnumerable <MailboxAddress> fromAddress, IEnumerable <MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable <AttachmentInfo> attachments = null, IEnumerable <MailboxAddress> ccAddress = null, IEnumerable <MailboxAddress> bccAddress = null, bool dispose = true) { var message = new MimeMessage(); message.From.AddRange(fromAddress); message.To.AddRange(toAddress); if (ccAddress != null && ccAddress.Any()) { message.Cc.AddRange(ccAddress); } if (bccAddress != null && bccAddress.Any()) { message.Bcc.AddRange(bccAddress); } message.Subject = subject; var body = new TextPart(textFormat) { Text = content }; MimeEntity entity = body; if (attachments != null) { var mult = new Multipart("mixed") { body }; foreach (var att in attachments) { if (att.Stream != null) { var attachment = string.IsNullOrWhiteSpace(att.ContentType) ? new MimePart() : new MimePart(att.ContentType); attachment.Content = new MimeContent(att.Stream); attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment); attachment.ContentTransferEncoding = att.ContentTransferEncoding; attachment.FileName = ConvertHeaderToBase64(att.FileName, Encoding.UTF8);//解决附件中文名问题 mult.Add(attachment); } } entity = mult; } message.Body = entity; message.Date = DateTime.Now; using (var client = new SmtpClient()) { //创建连接 await this.SmtpClientSetting(client).ConfigureAwait(false); await client.SendAsync(message).ConfigureAwait(false); await client.DisconnectAsync(true).ConfigureAwait(false); if (dispose && attachments != null) { foreach (var att in attachments) { att.Dispose(); } } } }
/// <summary> /// Sendsmtps the mail. /// </summary> /// <returns>The mail.</returns> /// <param name="texter">Texter.</param> /// <param name="header">Header.</param> /// <param name="image">Image.</param> /// <param name="hotelCode">Hotel code.</param> /// <param name="resNo">Res no.</param> public static async Task <bool> SendsmtpMail(string texter, string header, byte[] image, string hotelCode, string resNo) { try { var message = new MimeMessage(); message.From.Add(new MailboxAddress("Cinnamon Guest Feedback App", "*****@*****.**")); message.To.Add(new MailboxAddress("Thimira", "*****@*****.**")); message.Subject = "CGFS APP"; //message.Body = new TextPart(TextFormat.Html) //{ // Text = "<html>" + // "<h1>Cinnamon Guest Feedback App</h1>" + // "<h2>" + header + "</h2>" + // "<p>" + texter + "</p>" + // "</html>" //}; // create our message text, just like before (except don't set it as the message.Body) var body = new TextPart(TextFormat.Html) { Text = "<html>" + "<h1>Cinnamon Guest Feedback App</h1>" + "<h2>" + header + "</h2>" + "<p>" + texter + "</p>" + "</html>" }; MemoryStream memoryStream = new MemoryStream(image); // create an image attachment for the file located at path var attachment = new MimePart("image", "jpg") { Content = new MimeContent(memoryStream, ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = $"{hotelCode}_{resNo}.jpg" }; // now create the multipart/mixed container to hold the message text and the // image attachment var multipart = new Multipart("mixed"); multipart.Add(body); multipart.Add(attachment); // now set the multipart/mixed as the message body message.Body = multipart; using (var client = new SmtpClient()) { // For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS) client.ServerCertificateValidationCallback = (s, c, h, e) => true; await client.ConnectAsync("smtp.office365.com", 587, false); // Note: since we don't have an OAuth2 token, disable // the XOAUTH2 authentication mechanism. client.AuthenticationMechanisms.Remove("XOAUTH2"); // Note: only needed if the SMTP server requires authentication await client.AuthenticateAsync("*****@*****.**", Settings.SMTPPassword); await client.SendAsync(message); Console.WriteLine("E mail Sent"); return(true); } } catch (Exception) { return(false); } }
protected override void Execute(CodeActivityContext context) { string username = Email.Get(context); //发送端账号 string password = Password.Get(context); //发送端密码(这个客户端重置后的密码) string server = Server.Get(context); //邮件服务器 Int32 port = Port.Get(context); //端口号 string from = From.Get(context); //发送者地址(一般与发送账号相同) string name = Name.Get(context); //发送者名称 string[] receivers_To = Receivers_To.Get(context); //收件人 string[] receivers_Cc = Receivers_Cc.Get(context); //抄送 string[] recervers_Bcc = Receivers_Bcc.Get(context); //密送 string mailTopic = MailTopic.Get(context); //邮件的主题 string mailBody = MailBody.Get(context); //发送的邮件正文 //string[] attachFiles = AttachFiles.Get(context); //附件列表 MimeMessage transMsg = TransMailMessage.Get(context); try { List <string> attachments = Attachments ?? new List <string>(); foreach (InArgument <string> file in Files) { AddAttachments(attachments, file.Get(context)); } foreach (string item in AttachmentsCollection.Get(context).EmptyIfNull()) { AddAttachments(attachments, item); } MailKit.Net.Smtp.SmtpClient client = new MailKit.Net.Smtp.SmtpClient(); client.Connect(server, port, SecureConnection); client.Authenticate(username, password); var multipart = new Multipart("mixed"); MimeMessage msg = new MimeMessage(); if (name == null && from == null) { msg.From.Add((new MailboxAddress(username))); } else if (name == null && from != null) { msg.From.Add((new MailboxAddress(from))); } else if (name != null && from == null) { msg.From.Add((new MailboxAddress(name, username))); } else { msg.From.Add((new MailboxAddress(name, from))); } if (receivers_To != null) { foreach (string receiver in receivers_To) { msg.To.Add((new MailboxAddress(receiver))); } } if (receivers_Cc != null) { foreach (string receiver in receivers_Cc) { msg.Cc.Add((new MailboxAddress(receiver))); } } if (recervers_Bcc != null) { foreach (string receiver in recervers_Bcc) { msg.Bcc.Add((new MailboxAddress(receiver))); } } if (mailBody != null) { if (!IsBodyHtml) { var plain = new TextPart(TextFormat.Plain) { Text = mailBody }; multipart.Add(plain); } else { var Html = new TextPart(TextFormat.Html) { Text = mailBody }; multipart.Add(Html); } } else if (transMsg != null) { if (!IsBodyHtml) { var plain = new TextPart(TextFormat.Plain) { Text = transMsg.TextBody }; multipart.Add(plain); } else { var Html = new TextPart(TextFormat.Html) { Text = transMsg.HtmlBody }; multipart.Add(Html); } } else { var plain = new TextPart(TextFormat.Plain) { Text = "" }; multipart.Add(plain); } if (mailTopic != null) { msg.Subject = mailTopic; } else if (transMsg != null) { msg.Subject = transMsg.Subject; } msg.Priority = msgProperty; if (Files != null) { foreach (var p in Files) { try { if (!string.IsNullOrEmpty(p.ToString())) { var attimg = new MimePart() { Content = new MimeContent(File.OpenRead(p.ToString()), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(p.ToString()) }; multipart.Add(attimg); } } catch (FileNotFoundException ex) { SharedObject.Instance.Output(SharedObject.enOutputType.Error, "文件未找到,请检查有效路径", ex.Message); } } } if (transMsg != null) { foreach (MimeEntity part in transMsg.Attachments) { multipart.Add(part); } } msg.Body = multipart; try { client.Send(msg); Debug.WriteLine("发送成功"); } catch (System.Net.Mail.SmtpException ex) { Debug.WriteLine(ex.Message, "发送邮件出错"); } } catch (Exception e) { SharedObject.Instance.Output(SharedObject.enOutputType.Error, "发送邮件失败", e.Message); } }
public async Task SendAsync(Message message) { var sender = _config.Senders.FirstOrDefault(); if (sender != null && !string.IsNullOrEmpty(sender.Address)) { var mime = new MimeMessage(); mime.From.Add(new MailboxAddress(message.Sender.Name, message.Sender.Address)); mime.To.AddRange(message.Recipients.Where(_ => _.Type == Message.ActorType.Primary).Select(x => new MailboxAddress(x.Name, x.Address))); mime.Cc.AddRange(message.Recipients.Where(_ => _.Type == Message.ActorType.Subscriber).Select(x => new MailboxAddress(x.Name, x.Address))); mime.Bcc.AddRange(message.Recipients.Where(_ => _.Type == Message.ActorType.Logging).Select(x => new MailboxAddress(x.Name, x.Address))); mime.Subject = message.Subject; // msg properties var model = message.Arguments != null?Newtonsoft.Json.JsonConvert.DeserializeObject <EmailMessageModel>(Newtonsoft.Json.JsonConvert.SerializeObject(message.Arguments)) : new EmailMessageModel(); var body = new TextPart(model.IsHtml ? TextFormat.Html : TextFormat.Plain) { Text = message.Content }; var attachments = message.Attachments?.Where(_ => _.Content.Length > 0); if (attachments != null && attachments.Any()) { var multipart = new Multipart("mixed"); multipart.Add(body); foreach (var attachment in attachments) { multipart.Add(new MimePart() { FileName = attachment.Name ?? Guid.NewGuid().ToString(), Content = new MimeContent(new System.IO.MemoryStream(attachment.Content)), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64 }); } mime.Body = multipart; } else { mime.Body = body; } using (var client = new MailKit.Net.Smtp.SmtpClient()) { try { if (sender.SkipCertificateValidation) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; } await client.ConnectAsync(sender.Address, sender.Port == 0? 25 : sender.Port, sender.EnableSsl?MailKit.Security.SecureSocketOptions.Auto : MailKit.Security.SecureSocketOptions.None); client.AuthenticationMechanisms.Remove("XOAUTH2"); if (!string.IsNullOrEmpty(sender.UserName) && !string.IsNullOrEmpty(sender.Password)) { await client.AuthenticateAsync(sender.UserName, sender.Password).ConfigureAwait(false); } await client.SendAsync(mime).ConfigureAwait(false); } catch (Exception ex) when(ex is MailKit.Security.SslHandshakeException || ex is System.Net.Sockets.SocketException || ex is MailKit.ProtocolException) { _logger.LogError(ex, "Smtp connection error"); } catch (Exception ex) when(ex is MailKit.Security.AuthenticationException || ex is MailKit.Security.SaslException) { _logger.LogError(ex, "Smtp authentication error"); } catch (Exception ex) { _logger.LogWarning(ex, "Send email error"); } finally { await client.DisconnectAsync(true).ConfigureAwait(false); } } } }
/// <summary> /// Constructs the message body based on the text-based bodies, the linked resources, and the attachments. /// </summary> /// <remarks> /// Combines the <see cref="Attachments"/>, <see cref="LinkedResources"/>, <see cref="TextBody"/>, /// and <see cref="HtmlBody"/> into the proper MIME structure suitable for display in many common /// mail clients. /// </remarks> /// <returns>The message body.</returns> public MimeEntity ToMessageBody () { Multipart alternative = null; MimeEntity body = null; if (!string.IsNullOrEmpty (TextBody)) { var text = new TextPart ("plain"); text.Text = TextBody; if (!string.IsNullOrEmpty (HtmlBody)) { alternative = new Multipart ("alternative"); alternative.Add (text); body = alternative; } else { body = text; } } if (!string.IsNullOrEmpty (HtmlBody)) { var text = new TextPart ("html"); MimeEntity html; text.Text = HtmlBody; if (LinkedResources.Count > 0) { var related = new Multipart ("related"); related.ContentType.Parameters["type"] = "text/html"; related.Add (text); foreach (var resource in LinkedResources) related.Add (resource); html = related; } else { html = text; } if (alternative != null) alternative.Add (html); else body = html; } if (Attachments.Count > 0) { var mixed = new Multipart ("mixed"); if (body != null) mixed.Add (body); foreach (var attachment in Attachments) mixed.Add (attachment); body = mixed; } return body ?? new TextPart ("plain"); }
/// <summary> /// 获取MimePart /// </summary> /// <param name="item">附件基类</param> /// <returns></returns> private static MimePart GetMimePart(AttachmentBase item) { var mimeType = item.ContentType.ToString(); var contentType = ContentType.Parse(mimeType); var attachemt = item as Attachment; MimePart part; if (contentType.MediaType.Equals("text", StringComparison.OrdinalIgnoreCase)) { part = new TextPart(); } else { part = new MimePart(contentType); } if (attachemt != null) { //var disposition = attachemt.ContentDisposition.ToString(); //part.ContentDisposition = ContentDisposition.Parse(disposition); part.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment); } switch (item.TransferEncoding) { case System.Net.Mime.TransferEncoding.QuotedPrintable: part.ContentTransferEncoding = ContentEncoding.QuotedPrintable; break; case System.Net.Mime.TransferEncoding.Base64: part.ContentTransferEncoding = ContentEncoding.Base64; break; case System.Net.Mime.TransferEncoding.SevenBit: part.ContentTransferEncoding = ContentEncoding.SevenBit; break; case System.Net.Mime.TransferEncoding.EightBit: part.ContentTransferEncoding = ContentEncoding.EightBit; break; } if (item.ContentId != null) { part.ContentId = item.ContentId; } var stream = new MemoryBlockStream(); item.ContentStream.CopyTo(stream); stream.Position = 0; part.Content = new MimeContent(stream); if (attachemt != null) { // 解决中文文件名乱码 var charset = "GB18030"; part.ContentType.Parameters.Clear(); part.ContentDisposition.Parameters.Clear(); var fileName = attachemt.Name; part.ContentType.Parameters.Add(charset, "name", fileName); part.ContentDisposition.Parameters.Add(charset, "filename", fileName); // 解决文件名不能超过41字符 foreach (var parameter in part.ContentDisposition.Parameters) { parameter.EncodingMethod = ParameterEncodingMethod.Rfc2047; } foreach (var parameter in part.ContentType.Parameters) { parameter.EncodingMethod = ParameterEncodingMethod.Rfc2047; } } return(part); }
/// <summary> /// A modified version of CreateFromMailMessage() method in https://github.com/jstedfast/MimeKit/blob/master/MimeKit/MimeMessage.cs /// </summary> /// <param name="mail"></param> /// <returns></returns> public static MimeMessage ToMimeMessage(this MailMessage mail) { if (mail == null) { throw new ArgumentNullException(nameof(mail)); } var headers = new List <Header>(); foreach (var field in mail.Headers.AllKeys) { foreach (var value in mail.Headers.GetValues(field)) { headers.Add(new Header(field, value)); } } var message = new MimeMessage(headers.ToArray()); MimeEntity body = null; // Note: If the user has already sent their MailMessage via System.Net.Mail.SmtpClient, // then the following MailMessage properties will have been merged into the Headers, so // check to make sure our MimeMessage properties are empty before adding them. if (mail.Sender != null) { message.Sender = mail.Sender.ToMailboxAddress(); } if (mail.From != null) { message.Headers.Replace(HeaderId.From, string.Empty); message.From.Add(mail.From.ToMailboxAddress()); } if (mail.ReplyToList.Count > 0) { message.Headers.Replace(HeaderId.ReplyTo, string.Empty); message.ReplyTo.AddRange(mail.ReplyToList.ToInternetAddressList()); } if (mail.To.Count > 0) { message.Headers.Replace(HeaderId.To, string.Empty); message.To.AddRange(mail.To.ToInternetAddressList()); } if (mail.CC.Count > 0) { message.Headers.Replace(HeaderId.Cc, string.Empty); message.Cc.AddRange(mail.CC.ToInternetAddressList()); } if (mail.Bcc.Count > 0) { message.Headers.Replace(HeaderId.Bcc, string.Empty); message.Bcc.AddRange(mail.Bcc.ToInternetAddressList()); } if (mail.SubjectEncoding != null) { message.Headers.Replace(HeaderId.Subject, mail.SubjectEncoding, mail.Subject ?? string.Empty); } else { message.Subject = mail.Subject ?? string.Empty; } switch (mail.Priority) { case MailPriority.Normal: message.Headers.RemoveAll(HeaderId.XMSMailPriority); message.Headers.RemoveAll(HeaderId.Importance); message.Headers.RemoveAll(HeaderId.XPriority); message.Headers.RemoveAll(HeaderId.Priority); break; case MailPriority.High: message.Headers.Replace(HeaderId.Priority, "urgent"); message.Headers.Replace(HeaderId.Importance, "high"); message.Headers.Replace(HeaderId.XPriority, "2 (High)"); break; case MailPriority.Low: message.Headers.Replace(HeaderId.Priority, "non-urgent"); message.Headers.Replace(HeaderId.Importance, "low"); message.Headers.Replace(HeaderId.XPriority, "4 (Low)"); break; } if (!string.IsNullOrEmpty(mail.Body)) { var text = new TextPart(mail.IsBodyHtml ? "html" : "plain"); text.SetText(mail.BodyEncoding ?? Encoding.UTF8, mail.Body); body = text; } if (mail.AlternateViews.Count > 0) { var alternative = new MultipartAlternative(); if (body != null) { alternative.Add(body); } foreach (var view in mail.AlternateViews) { var part = GetMimePart(view); if (view.BaseUri != null) { part.ContentLocation = view.BaseUri; } if (view.LinkedResources.Count > 0) { var type = part.ContentType.MediaType + "/" + part.ContentType.MediaSubtype; var related = new MultipartRelated(); related.ContentType.Parameters.Add("type", type); if (view.BaseUri != null) { related.ContentLocation = view.BaseUri; } related.Add(part); foreach (var resource in view.LinkedResources) { part = GetMimePart(resource); if (resource.ContentLink != null) { part.ContentLocation = resource.ContentLink; } related.Add(part); } alternative.Add(related); } else { alternative.Add(part); } } body = alternative; } if (body == null) { body = new TextPart(mail.IsBodyHtml ? "html" : "plain"); } if (mail.Attachments.Count > 0) { var mixed = new Multipart("mixed"); if (body != null) { mixed.Add(body); } foreach (var attachment in mail.Attachments) { mixed.Add(GetMimePart(attachment)); } body = mixed; } message.Body = body; return(message); }
/// <summary> /// 得到电子邮件对象 /// </summary> /// <param name="mailSettings">邮件配置文件类</param> /// <returns>MailMessage对象</returns> private MimeMessage GetMailMessage(MailConfig mailSettings) { MimeMessage message = new MimeMessage(); //收件人地址 foreach (MailboxAddress address in this.MailToAddressList) { message.To.Add(address); } //抄送人地址 if (this.MailCopyToAddressList != null) { foreach (MailboxAddress address2 in this.MailCopyToAddressList) { message.Cc.Add(address2); } } //回复地址 if (this.ReplyTo != null) { message.ReplyTo.Add(this.ReplyTo); } //发件人地址 if (!string.IsNullOrEmpty(this.FromName)) { message.From.Add(new MailboxAddress(FromName, mailSettings.MailFrom)); } else { message.From.Add(new MailboxAddress(mailSettings.MailFrom)); } message.Priority = this.Priority; message.Subject = this.Subject; //添加正文内容 TextPart body; if (IsBodyHtml) { body = new TextPart(TextFormat.Html); } else { body = new TextPart(TextFormat.Plain); } body.SetText(Encoding.UTF8, MailBody); var multipart = new Multipart("mixed"); multipart.Add(body); //添加附件 if (!string.IsNullOrWhiteSpace(AttachmentFilePath)) { //生产一个绝对路径 var absolutePath = FileHelper.MapPath(AttachmentFilePath); //附件 var attachment = new MimePart() { //读取文件(只能用绝对路径) Content = new MimeContent(File.OpenRead(absolutePath), ContentEncoding.Default), //ContentObject = new ContentObject(File.OpenRead(absolutePath), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, //文件名字 FileName = Path.GetFileName(absolutePath) }; //添加附件 multipart.Add(attachment); } message.Body = multipart; return(message); }
public static bool IsContentHtml([NotNull] this TextPart textPart) { return(textPart.ContentType.IsMimeType("text", "html")); }
protected internal override void VisitTextPart(TextPart entity) { TextPart++; base.VisitTextPart(entity); }
/// <summary> /// Gets the ready made body part for a mail message either /// - as TextPart, if there are no inline attachments /// - as MultipartRelated with a TextPart and one or more MimeParts of type inline attachments /// </summary> public override MimeEntity GetBodyPart() { // remove all Script elements, because they cannot be used in mail messages foreach (var element in _htmlDocument.All.Where(e => e is IHtmlScriptElement)) { element.Remove(); } // set the HTML title tag from email subject var titleEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlTitleElement) as IHtmlTitleElement; if (titleEle != null) { titleEle.Text = _mailMergeMessage.SearchAndReplaceVars(_mailMergeMessage.Subject, _dataItem); } // read the <base href="..."> tag in order to find the embedded image files later on var baseEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlBaseElement) as IHtmlBaseElement; var baseDir = baseEle?.Href ?? string.Empty; // only replace the base url if it was not set programmatically if (string.IsNullOrEmpty(_docBaseUrl)) { _docBaseUrl = string.IsNullOrEmpty(baseDir) ? string.Empty : MakeUri(baseDir); } // remove if base tag is local file reference, because it's not usable in the resulting HTML if (baseEle != null && baseDir.StartsWith(Uri.UriSchemeFile)) { baseEle.Remove(); } ReplaceImgSrcByCid(); // replace placeholders only in the HTML Body, because e.g. // in the header there may be CSS definitions with curly brace which collide with SmartFormat {placeholders} _htmlDocument.Body.InnerHtml = _mailMergeMessage.SearchAndReplaceVars(_htmlDocument.Body.InnerHtml, _dataItem); var htmlTextPart = new TextPart("html") { ContentTransferEncoding = Tools.IsSevenBit(DocHtml) ? ContentEncoding.SevenBit : TextTransferEncoding != ContentEncoding.SevenBit ? TextTransferEncoding : ContentEncoding.QuotedPrintable, }; htmlTextPart.SetText(CharacterEncoding, DocHtml); htmlTextPart.ContentType.Charset = CharacterEncoding.HeaderName; // RFC 2045 Section 5.1 - http://www.ietf.org; htmlTextPart.ContentId = MimeUtils.GenerateMessageId(); if (!InlineAtt.Any()) { return(htmlTextPart); } /* * multipart/related * text/html * image/jpeg * image/png * image/gif... */ var mpr = new MultipartRelated { htmlTextPart }; // Produce attachments as part of the multipart/related MIME part, // as described in RFC2387 // Some older clients may need Inline Attachments instead of LinkedResources: // RFC2183: 2.1 The Inline Disposition Type // A bodypart should be marked `inline' if it is intended to be displayed automatically upon display of the message. Inline // bodyparts should be presented in the order in which they occur, subject to the normal semantics of multipart messages. foreach (var ia in InlineAtt) { try { // create an inline image attachment for the file located at path var attachment = new AttachmentBuilder(ia, CharacterEncoding, TextTransferEncoding, BinaryTransferEncoding).GetAttachment(); attachment.ContentDisposition = new MimeKit.ContentDisposition(MimeKit.ContentDisposition.Inline); mpr.Add(attachment); } catch (FileNotFoundException) { BadInlineFiles.Add(ia.Filename); } catch (IOException) { BadInlineFiles.Add(ia.Filename); } } return(mpr); }
/// <summary> /// Prepares the mail message part (plain text and/or HTML: /// Replacing placeholders with their values and setting correct encoding. /// </summary> private void BuildTextMessagePart(object dataIteam) { _badInlineFiles.Clear(); _textMessagePart = null; MultipartAlternative alternative = null; // create the plain text body part TextPart plainTextPart = null; if (!string.IsNullOrEmpty(PlainText)) { var plainText = SearchAndReplaceVars(PlainText, dataIteam); plainTextPart = (TextPart) new PlainBodyBuilder(plainText) { TextTransferEncoding = Config.TextTransferEncoding, CharacterEncoding = Config.CharacterEncoding }.GetBodyPart(); if (!string.IsNullOrEmpty(HtmlText)) { // there is plain text AND html text alternative = new MultipartAlternative { plainTextPart }; _textMessagePart = alternative; } else { // there is only a plain text part, which could even be null _textMessagePart = plainTextPart; } } if (!string.IsNullOrEmpty(HtmlText)) { // create the HTML text body part with any linked resources // replacing any placeholders in the text or files with variable values var htmlBody = new HtmlBodyBuilder(this, dataIteam) { DocBaseUrl = Config.FileBaseDirectory, TextTransferEncoding = Config.TextTransferEncoding, BinaryTransferEncoding = Config.BinaryTransferEncoding, CharacterEncoding = Config.CharacterEncoding }; _inlineAttExternal.ForEach(ia => htmlBody.InlineAtt.Add(ia)); InlineAttachments = htmlBody.InlineAtt; htmlBody.BadInlineFiles.ToList().ForEach(f => _badInlineFiles.Add(f)); if (alternative != null) { alternative.Add(htmlBody.GetBodyPart()); _textMessagePart = alternative; } else { _textMessagePart = htmlBody.GetBodyPart(); } } else { InlineAttachments = new HashSet <FileAttachment>(); _badInlineFiles = new HashSet <string>(); } }
public virtual void TestSecureMimeSigning() { var body = new TextPart("plain") { Text = "This is some cleartext that we'll end up signing..." }; var self = new MailboxAddress("MimeKit UnitTests", "*****@*****.**"); var message = new MimeMessage { Subject = "Test of signing with S/MIME" }; message.From.Add(self); message.Body = body; using (var ctx = CreateContext()) { Assert.IsTrue(ctx.CanSign(self)); message.Sign(ctx); Assert.IsInstanceOf <MultipartSigned> (message.Body, "The message body should be a multipart/signed."); var multipart = (MultipartSigned)message.Body; Assert.AreEqual(2, multipart.Count, "The multipart/signed has an unexpected number of children."); var protocol = multipart.ContentType.Parameters["protocol"]; Assert.AreEqual(ctx.SignatureProtocol, protocol, "The multipart/signed protocol does not match."); Assert.IsInstanceOf <TextPart> (multipart[0], "The first child is not a text part."); Assert.IsInstanceOf <ApplicationPkcs7Signature> (multipart[1], "The second child is not a detached signature."); var signatures = multipart.Verify(ctx); Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify(); Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms; int i = 0; Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[i++], "Expected AES-256 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[i++], "Expected AES-192 capability"); Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[i++], "Expected AES-128 capability"); if (ctx.IsEnabled(EncryptionAlgorithm.Idea)) { Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[i++], "Expected IDEA capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Cast5)) { Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[i++], "Expected Cast5 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia256)) { Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[i++], "Expected Camellia-256 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia192)) { Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[i++], "Expected Camellia-192 capability"); } if (ctx.IsEnabled(EncryptionAlgorithm.Camellia128)) { Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[i++], "Expected Camellia-128 capability"); } Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[i++], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[i++], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[i++], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[i++], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[i++], "Expected RC2-40 capability"); } } }
/// <summary> /// Gets the ready made body part for a mail message either /// - as TextPart, if there are no inline attachments /// - as MultipartRelated with a TextPart and one or more MimeParts of type inline attachments /// </summary> public override MimeEntity GetBodyPart() { // remove all Script elements, because they cannot be used in mail messages foreach (var element in _htmlDocument.All.Where(e => e is IHtmlScriptElement).ToList()) { element.Remove(); } // set the HTML title tag from email subject var titleEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlTitleElement) as IHtmlTitleElement; if (titleEle != null) { titleEle.Text = _mailMergeMessage.SearchAndReplaceVars(_mailMergeMessage.Subject, _dataItem); } // read the <base href="..."> tag in order to find the embedded image files later on var baseEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlBaseElement) as IHtmlBaseElement; var baseDir = baseEle?.Href == null ? null : new Uri(baseEle.Href); // only replace the base url if it was not set programmatically if (baseDir != null && _docBaseUri == new Uri(_defaultDocBaseUri)) { _docBaseUri = baseDir; } // remove if base tag is local file reference, because it's not usable in the resulting HTML if (baseEle != null && baseDir != null && baseDir.Scheme == UriScheme.File) { baseEle.Remove(); } ReplaceImgSrcByCid(); // replace placeholders only in the HTML Body, because e.g. // in the header there may be CSS definitions with curly brace which collide with SmartFormat {placeholders} _htmlDocument.Body.InnerHtml = _mailMergeMessage.SearchAndReplaceVars(_htmlDocument.Body.InnerHtml, _dataItem); var htmlTextPart = new TextPart("html") { ContentTransferEncoding = TextTransferEncoding }; htmlTextPart.SetText(CharacterEncoding, DocHtml); // MimeKit.ContentType.Charset is set using CharacterEncoding htmlTextPart.ContentId = MimeUtils.GenerateMessageId(); if (!InlineAtt.Any()) { return(htmlTextPart); } /* * multipart/related * text/html * image/jpeg * image/png * image/gif... */ var mpr = new MultipartRelated(htmlTextPart); // Produce attachments as part of the multipart/related MIME part, // as described in RFC2387 // Some older clients may need Inline Attachments instead of LinkedResources: // RFC2183: 2.1 The Inline Disposition Type // A bodypart should be marked `inline' if it is intended to be displayed automatically upon display of the message. Inline // bodyparts should be presented in the order in which they occur, subject to the normal semantics of multipart messages. foreach (var ia in InlineAtt) { try { var readyInlineAtt = new FileAttachment(_mailMergeMessage.SearchAndReplaceVarsInFilename(ia.Filename, _dataItem), _mailMergeMessage.SearchAndReplaceVars(ia.DisplayName, _dataItem)); // create an inline image attachment for the file located at path var attachment = new AttachmentBuilder(readyInlineAtt, CharacterEncoding, TextTransferEncoding, BinaryTransferEncoding).GetAttachment(); attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Inline); attachment.ContentId = ia.DisplayName; attachment.FileName = null; // not needed for inline attachments, save some space mpr.Add(attachment); } catch (FileNotFoundException) { BadInlineFiles.Add(ia.Filename); } catch (IOException) { BadInlineFiles.Add(ia.Filename); } } return(mpr); }
public void TestArgumentExceptions() { var path = Path.Combine("..", "..", "TestData", "smime", "smime.p12"); var entity = new TextPart("plain") { Text = "This is some text..." }; var mailbox = new MailboxAddress("MimeKit UnitTests", "*****@*****.**"); var recipients = new CmsRecipientCollection(); var signer = new CmsSigner(path, "no.secret"); var mailboxes = new [] { mailbox }; recipients.Add(new CmsRecipient(signer.Certificate)); using (var ctx = new TemporarySecureMimeContext()) { ctx.Import(path, "no.secret"); // Compress Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(ctx, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(null)); // Encrypt Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(null, mailboxes, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(null, recipients, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, (IEnumerable <MailboxAddress>)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, (CmsRecipientCollection)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, recipients, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, mailboxes, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt((IEnumerable <MailboxAddress>)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt((CmsRecipientCollection)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(recipients, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(mailboxes, null)); // Sign Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(null, mailbox, DigestAlgorithm.Sha1, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(null, signer, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, (MailboxAddress)null, DigestAlgorithm.Sha1, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, (CmsSigner)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, mailbox, DigestAlgorithm.Sha1, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, signer, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign((MailboxAddress)null, DigestAlgorithm.Sha1, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign((CmsSigner)null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(mailbox, DigestAlgorithm.Sha1, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(signer, null)); // SignAndEncrypt Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, mailbox, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, null, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, mailbox, DigestAlgorithm.Sha1, null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, mailbox, DigestAlgorithm.Sha1, mailboxes, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, DigestAlgorithm.Sha1, mailboxes, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(mailbox, DigestAlgorithm.Sha1, null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(mailbox, DigestAlgorithm.Sha1, mailboxes, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, signer, recipients, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, null, recipients, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, signer, null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, signer, recipients, null)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, recipients, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(signer, null, entity)); Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(signer, recipients, null)); var compressed = ApplicationPkcs7Mime.Compress(ctx, entity); var encrypted = ApplicationPkcs7Mime.Encrypt(recipients, entity); var signed = ApplicationPkcs7Mime.Sign(signer, entity); // Decompress Assert.Throws <ArgumentNullException> (() => compressed.Decompress(null)); Assert.Throws <InvalidOperationException> (() => encrypted.Decompress(ctx)); Assert.Throws <InvalidOperationException> (() => signed.Decompress(ctx)); // Decrypt Assert.Throws <ArgumentNullException> (() => encrypted.Decrypt(null)); Assert.Throws <InvalidOperationException> (() => compressed.Decrypt(ctx)); Assert.Throws <InvalidOperationException> (() => signed.Decrypt(ctx)); // Verify Assert.Throws <ArgumentNullException> (() => { MimeEntity mime; signed.Verify(null, out mime); }); Assert.Throws <InvalidOperationException> (() => { MimeEntity mime; compressed.Verify(ctx, out mime); }); Assert.Throws <InvalidOperationException> (() => { MimeEntity mime; encrypted.Verify(ctx, out mime); }); } }
void Render(MimeEntity entity) { var related = entity as MultipartRelated; if (related != null) { RenderMultipartRelated(related); return; } var multipart = entity as Multipart; var text = entity as TextPart; // check if the entity is a multipart if (multipart != null) { if (multipart.ContentType.IsMimeType("multipart", "alternative")) { // A multipart/alternative is just a collection of alternate views. // The last part is the format that most closely matches what the // user saw in his or her email client's WYSIWYG editor. TextPart preferred = null; for (int i = multipart.Count; i > 0; i--) { related = multipart[i - 1] as MultipartRelated; if (related != null) { var root = related.Root; if (root != null && root.ContentType.IsMimeType("text", "html")) { RenderMultipartRelated(related); return; } continue; } text = multipart[i - 1] as TextPart; if (text == null) { continue; } if (text.IsHtml) { // we prefer html over plain text preferred = text; break; } if (preferred == null) { // we'll take what we can get preferred = text; } } if (preferred != null) { RenderText(preferred); } } else if (multipart.Count > 0) { // At this point we know we're not dealing with a multipart/related or a // multipart/alternative, so we can safely treat this as a multipart/mixed // even if it's not. // The main message body is usually the first part of a multipart/mixed. I // suppose that it might be better to render the first text/* part instead // (in case it's not the first part), but that's rare and probably also // indicates that the text is meant to be displayed between the other parts // (probably images or video?) in some sort of pseudo-multimedia "document" // layout. Modern clients don't do this, they use HTML or RTF instead. Render(multipart[0]); } } else if (text != null) { // render the text part RenderText(text); } else { // message/rfc822 part } }
public override VerificationResult Report() { VerificationResult veridationResult = new VerificationResult(); if (Core.Env.SystemConnectionStringSettings == null) { return(veridationResult); } if (!string.IsNullOrWhiteSpace(ReportSampleSql) && ReportSampleSql.ToLower().Contains("limit")) { Logger.Log("SQL contains 'LIMIT'.", Level.Error); return(veridationResult); } if (Verifiers != null && Verifiers.Count > 0 && EmailTo != null && EmailTo.Count > 0 && !string.IsNullOrWhiteSpace(EmailHost)) { using (var conn = Core.Env.DataConnectionStringSettings.CreateDbConnection()) { var emailBody = new StringBuilder(); var hasProperties = Properties != null; emailBody.Append( "<html><head>" + "<meta charset=\"utf-8\">" + "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" + "<meta name=\"viewport\" content=\"width=device-width initial-scale=1.0\">" + $"<title>{Subject}: {DateTime.Now}</title>" + "<style>" + "table {border-collapse: collapse;border-spacing: 0;border-left: 1px solid #888;border-top: 1px solid #888;background: #efefef;}th, td {border-right: 1px solid #888;border-bottom: 1px solid #888;padding: 5px 15px;}th {font-weight: bold;background: #ccc;}" + "</style>" + "</head>" + "<body style=\"background-color:#FAF7EC\">" + $"<h2>{Subject}: {DateTime.Now}</h2>" + (hasProperties ? $"<strong>Analyst: </strong>{Properties.Owner}" : "") + (hasProperties ? $" <strong>Developer: </strong>{Properties.Developer}" : "") + (hasProperties ? $" <strong>Date: </strong>{Properties.Date}" : "") + (hasProperties ? $" <strong>Description: </strong>{Description}" : "") + "<br/><br/>" + "<table>" + "<thead>" + "<tr>" + "<th>Item</th>" + "<th>Rule</th>" + "<th>SQL</th>" + "<th>Expected</th>" + "<th>Actual</th>" + "<th>Result</th>" + "<th>Time</th> " + "</tr>" + "</thead>" + "<tbody>" ); var success = true; foreach (var verifier in Verifiers) { var result = verifier.Verify(conn); emailBody.AppendLine(result.Report); if (success && !result.Pass) { success = false; } } veridationResult.PassVeridation = success; emailBody.Append("</tbody></table><br/>"); if (!string.IsNullOrWhiteSpace(ReportSampleSql)) { emailBody.Append("<strong>数据样本</strong><br/><br/>"); emailBody.Append(conn.ToHtml($"{ReportSampleSql} LIMIT 100;")); } emailBody.Append("<br/><br/></body></html>"); var message = new MimeMessage(); var displayName = string.IsNullOrWhiteSpace(EmailDisplayName) ? "DotnetSpider Alert" : EmailDisplayName; message.From.Add(new MailboxAddress(displayName, EmailAccount)); foreach (var emailTo in EmailTo) { message.To.Add(new MailboxAddress(emailTo, emailTo)); } message.Subject = $"{Subject}: {(success ? "Success" : "Failed")}"; var html = new TextPart("html") { Text = HttpUtility.HtmlDecode(emailBody.ToString()) }; var multipart = new Multipart("mixed") { html }; if (veridationResult.PassVeridation && !string.IsNullOrWhiteSpace(ExportDataSql) && !string.IsNullOrWhiteSpace(ExportDataFileName)) { var path = conn.Export(ExportDataSql, $"{ExportDataFileName}_{DateTime.Now:yyyyMMddhhmmss}", true); var attachment = new MimePart("excel", "xlsx") { ContentObject = new ContentObject(File.OpenRead(path)), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(path) }; multipart.Add(attachment); } message.Body = multipart; using (var client = new MailKit.Net.Smtp.SmtpClient()) { client.Connect(EmailHost, EmailPort); // Note: only needed if the SMTP server requires authentication client.Authenticate(EmailAccount, EmailPassword); client.Send(message); client.Disconnect(true); } } } return(veridationResult); }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; var recipient = new EmailAddress(); var sender = new EmailAddress(); string normalizedSubject = null; string subjectPrefix = null; MailboxAddress mailbox; var msgid = false; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); msgid = true; } break; case TnefPropertyId.TnefCorrelationKey: // According to MSDN, PidTagTnefCorrelationKey is a unique key that is // meant to be used to tie the TNEF attachment to the encapsulating // message. It can be a string or a binary blob. It seems that most // implementations use the Message-Id string, so if this property // value looks like a Message-Id, then us it as one (unless we get a // InternetMessageId property, in which case we use that instead. if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { if (!msgid) { var value = prop.ReadValueAsString(); if (value.Length > 5 && value[0] == '<' && value[value.Length - 1] == '>' && value.IndexOf('@') != -1) { message.MessageId = value; } } } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); } break; case TnefPropertyId.SubjectPrefix: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { subjectPrefix = prop.ReadValueAsString(); } break; case TnefPropertyId.NormalizedSubject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { normalizedSubject = prop.ReadValueAsString(); } break; case TnefPropertyId.SenderName: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { sender.Name = prop.ReadValueAsString(); } break; case TnefPropertyId.SenderEmailAddress: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { sender.Addr = prop.ReadValueAsString(); } break; case TnefPropertyId.SenderSearchKey: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { sender.SearchKey = prop.ReadValueAsString(); } break; case TnefPropertyId.SenderAddrtype: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { sender.AddrType = prop.ReadValueAsString(); } break; case TnefPropertyId.ReceivedByName: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { recipient.Name = prop.ReadValueAsString(); } break; case TnefPropertyId.ReceivedByEmailAddress: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { recipient.Addr = prop.ReadValueAsString(); } break; case TnefPropertyId.ReceivedBySearchKey: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { recipient.SearchKey = prop.ReadValueAsString(); } break; case TnefPropertyId.ReceivedByAddrtype: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { recipient.AddrType = prop.ReadValueAsString(); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); var converter = new RtfCompressedToRtf(); var content = new MemoryBlockStream(); using (var filtered = new FilteredStream(content)) { filtered.Add(converter); using (var compressed = prop.GetRawValueReadStream()) { compressed.CopyTo(filtered, 4096); filtered.Flush(); } } rtf.Content = new MimeContent(content); content.Position = 0; builder.Attachments.Add(rtf); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); Encoding encoding; if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode) { encoding = Encoding.GetEncoding(reader.MessageCodepage); } else { encoding = CharsetUtils.UTF8; } html.SetText(encoding, prop.ReadValueAsString()); builder.Attachments.Add(html); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); Encoding encoding; if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode) { encoding = Encoding.GetEncoding(reader.MessageCodepage); } else { encoding = CharsetUtils.UTF8; } plain.SetText(encoding, prop.ReadValueAsString()); builder.Attachments.Add(plain); } break; case TnefPropertyId.Importance: // https://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx switch (prop.ReadValueAsInt32()) { case 2: message.Importance = MessageImportance.High; break; case 1: message.Importance = MessageImportance.Normal; break; case 0: message.Importance = MessageImportance.Low; break; } break; case TnefPropertyId.Priority: // https://msdn.microsoft.com/en-us/library/ee159473(v=exchg.80).aspx switch (prop.ReadValueAsInt32()) { case 1: message.Priority = MessagePriority.Urgent; break; case 0: message.Priority = MessagePriority.Normal; break; case -1: message.Priority = MessagePriority.NonUrgent; break; } break; case TnefPropertyId.Sensitivity: // https://msdn.microsoft.com/en-us/library/ee217353(v=exchg.80).aspx // https://tools.ietf.org/html/rfc2156#section-5.3.4 switch (prop.ReadValueAsInt32()) { case 1: message.Headers[HeaderId.Sensitivity] = "Personal"; break; case 2: message.Headers[HeaderId.Sensitivity] = "Private"; break; case 3: message.Headers[HeaderId.Sensitivity] = "Company-Confidential"; break; case 0: message.Headers.Remove(HeaderId.Sensitivity); break; } break; } } if (string.IsNullOrEmpty(message.Subject) && !string.IsNullOrEmpty(normalizedSubject)) { if (!string.IsNullOrEmpty(subjectPrefix)) { message.Subject = subjectPrefix + normalizedSubject; } else { message.Subject = normalizedSubject; } } if (sender.TryGetMailboxAddress(out mailbox)) { message.From.Add(mailbox); } if (recipient.TryGetMailboxAddress(out mailbox)) { message.To.Add(mailbox); } }
void Render(TextPart text) { string html; if (!text.ContentType.Matches("text", "html")) { var builder = new StringBuilder("<html><body><p>"); var plain = text.Text; for (int i = 0; i < plain.Length; i++) { switch (plain[i]) { case ' ': builder.Append(" "); break; case '"': builder.Append("""); break; case '&': builder.Append("&"); break; case '<': builder.Append("<"); break; case '>': builder.Append(">"); break; case '\r': break; case '\n': builder.Append("<p>"); break; case '\t': for (int j = 0; j < 8; j++) { builder.Append(" "); } break; default: if (char.IsControl(plain[i]) || plain[i] > 127) { int unichar; if (i + 1 < plain.Length && char.IsSurrogatePair(plain[i], plain[i + 1])) { unichar = char.ConvertToUtf32(plain[i], plain[i + 1]); } else { unichar = plain[i]; } builder.AppendFormat("&#{0};", unichar); } else { builder.Append(plain[i]); } break; } } builder.Append("</body></html>"); html = builder.ToString(); } else { html = text.Text; } webView.LoadHtmlString(html, new NSUrl("index.html")); }
void RenderMultipartRelated(MultipartRelated related) { var root = related.Root; var multipart = root as Multipart; var text = root as TextPart; if (multipart != null) { // Note: the root document can sometimes be a multipart/alternative. // A multipart/alternative is just a collection of alternate views. // The last part is the format that most closely matches what the // user saw in his or her email client's WYSIWYG editor. for (int i = multipart.Count; i > 0; i--) { var body = multipart[i - 1] as TextPart; if (body == null) { continue; } // our preferred mime-type is text/html if (body.ContentType.Matches("text", "html")) { text = body; break; } if (text == null) { text = body; } } } // check if we have a text/html document if (text != null && text.ContentType.Matches("text", "html")) { var doc = new HtmlAgilityPack.HtmlDocument(); var saved = new Dictionary <MimePart, string> (); TextPart html; doc.LoadHtml(text.Text); // find references to related MIME parts and replace them with links to links to the saved attachments foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]")) { var src = img.Attributes["src"]; int index; Uri uri; if (src == null || src.Value == null) { continue; } // parse the <img src=...> attribute value into a Uri if (Uri.IsWellFormedUriString(src.Value, UriKind.Absolute)) { uri = new Uri(src.Value, UriKind.Absolute); } else { uri = new Uri(src.Value, UriKind.Relative); } // locate the index of the attachment within the multipart/related (if it exists) if ((index = related.IndexOf(uri)) != -1) { var attachment = related[index] as MimePart; // make sure the referenced part is a MimePart (as opposed to another Multipart or MessagePart) if (attachment != null) { string fileName; // save the attachment (if we haven't already saved it) if (!saved.TryGetValue(attachment, out fileName)) { fileName = attachment.FileName; if (string.IsNullOrEmpty(fileName)) { fileName = Guid.NewGuid().ToString(); } using (var stream = File.Create(fileName)) attachment.ContentObject.DecodeTo(stream); saved.Add(attachment, fileName); } // replace the <img src=...> value with the local file name src.Value = "file://" + Path.GetFullPath(fileName); } } } if (saved.Count > 0) { // we had to make some modifications to the original html part, so create a new // (temporary) text/html part to render html = new TextPart("html"); using (var writer = new StringWriter()) { doc.Save(writer); html.Text = writer.GetStringBuilder().ToString(); } } else { html = text; } RenderTextPart(html); } else { // we don't know what we have, so render it as an entity RenderEntity(related.Root); } }
static void ExtractMapiProperties (TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; while (prop.ReadNextProperty ()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString (); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString (); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart ("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf (); var content = new MemoryStream (); using (var filtered = new FilteredStream (content)) { filtered.Add (converter); using (var compressed = prop.GetRawValueReadStream ()) { compressed.CopyTo (filtered, 4096); filtered.Flush (); } } rtf.ContentObject = new ContentObject (content); content.Position = 0; builder.Attachments.Add (rtf); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart ("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString (); builder.Attachments.Add (html); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart ("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString (); builder.Attachments.Add (plain); } break; } } }
public bool CheckRequirements(TextPart target) { bool returnValue = true; for (int requirementCounter = 0; requirementCounter < target.requirements.Count; requirementCounter++) { Requirement requirement = target.requirements [requirementCounter]; if (requirement.type == RequirementType.and) { if (returnValue == false) { continue; } returnValue = CheckRequirement (requirement); } else { if (returnValue == true) { return true; } returnValue = CheckRequirement (requirement); } } return returnValue; }