public ProtectAttachment(Microsoft.Office.Interop.Outlook.Attachment attachment) : this() { // 17470 [WS 8.0] Protect files is not enabled when .msg with no subject is attached through Right click->send To->Mail Recipient.ZenQ Name = attachment.DisplayName ?? ""; var filename = string.Empty; filename = attachment.FileName.ToLower() == ".msg" ? Guid.NewGuid().ToString() + ".msg" : attachment.FileName; // -- Index = attachment.Index.ToString(CultureInfo.InvariantCulture); var wsAttachment = attachment as WsAttachment; if (wsAttachment != null) { Id = wsAttachment.Id.ToString(); RecordKey = wsAttachment.RecordKey; } _lcofm = new LocalCopyOfFileManager(); filename = _lcofm.GetLocalCopyOfFileTarget(filename); attachment.SaveAsFile(filename); var lah = new LargeAttachmentHelper(filename); if (lah.IsLargeAttachment) { LargeAttachmentFileName = filename; var tempfile = _lcofm.GetLocalCopyOfFileTarget(Path.GetFileName(lah.ActualPath)); System.IO.File.Copy(lah.ActualPath, tempfile, true); filename = tempfile; Name = Path.GetFileName(filename); } File = FcsFileFactory.Create(filename, Name); Position = attachment.Position; FileName = filename; }
void HandlePgpMime(Outlook.MailItem mailItem, Microsoft.Office.Interop.Outlook.Attachment encryptedMime, Microsoft.Office.Interop.Outlook.Attachment sigMime, string sigHash = "sha1") { logger.Trace("> HandlePgpMime"); CryptoContext Context = null; string sig = null; byte[] cyphertext = null; string cleartext = mailItem.Body; // 1. Decrypt attachement if (encryptedMime != null) { logger.Trace("Decrypting cypher text."); var tempfile = Path.GetTempFileName(); encryptedMime.SaveAsFile(tempfile); cyphertext = File.ReadAllBytes(tempfile); File.Delete(tempfile); var clearbytes = DecryptAndVerify(mailItem.To, cyphertext, out Context); if (clearbytes == null) return; cleartext = this._encoding.GetString(clearbytes); } // 2. Verify signature if (sigMime != null) { Context = new CryptoContext(Passphrase); var Crypto = new PgpCrypto(Context); Outlook.OlBodyFormat mailType = mailItem.BodyFormat; try { logger.Trace("Verify detached signature"); var tempfile = Path.GetTempFileName(); sigMime.SaveAsFile(tempfile); var detachedsig = File.ReadAllText(tempfile); File.Delete(tempfile); // Build up a clearsignature format for validation // the rules for are the same with the addition of two heaer fields. // Ultimately we need to get these fields out of email itself. var encoding = GetEncodingFromMail(mailItem); var clearsig = string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\n\r\n", sigHash); //clearsig += "Content-Type: text/plain; charset=ISO-8859-1\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n"; clearsig += "Content-Type: text/plain; charset=" + encoding.BodyName.ToUpper()+ "\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n"; clearsig += PgpClearDashEscapeAndQuoteEncode( encoding.GetString( (byte[])mailItem.PropertyAccessor.GetProperty( "http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102"))); clearsig += "\r\n"+detachedsig; logger.Trace(clearsig); if (Crypto.VerifyClear(_encoding.GetBytes(clearsig))) { Context = Crypto.Context; var message = "** Valid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId + ".\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = message + mailItem.Body; } } else { Context = Crypto.Context; var message = "** Invalid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId + ".\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = message + mailItem.Body; } } } catch (PublicKeyNotFoundException ex) { logger.Debug(ex.ToString()); Context = Crypto.Context; var message = "** Unable to verify signature, missing public key.\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = message + mailItem.Body; } } catch (Exception ex) { logger.Debug(ex.ToString()); this.Passphrase = null; WriteErrorData("VerifyEmail", ex); MessageBox.Show( ex.Message, "Outlook Privacy Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } if (Context == null) return; // Extract files from MIME data SharpMessage msg = new SharpMessage(cleartext); string body = mailItem.Body; var DecryptAndVerifyHeaderMessage = "** "; if (Context.IsEncrypted) DecryptAndVerifyHeaderMessage += "Message decrypted. "; if (Context.FailedIntegrityCheck) DecryptAndVerifyHeaderMessage += "Failed integrity check! "; if (Context.IsSigned && Context.SignatureValidated) { DecryptAndVerifyHeaderMessage += "Valid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId; } else if (Context.IsSigned) { DecryptAndVerifyHeaderMessage += "Invalid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId + "."; } else DecryptAndVerifyHeaderMessage += "Message was unsigned."; DecryptAndVerifyHeaderMessage += "\n\n"; if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = DecryptAndVerifyHeaderMessage + msg.Body; } else if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatHTML) { if (!msg.Body.TrimStart().ToLower().StartsWith("<html")) { body = DecryptAndVerifyHeaderMessage + msg.Body; body = System.Net.WebUtility.HtmlEncode(body); body = body.Replace("\n", "<br />"); mailItem.HTMLBody = "<html><head></head><body>" + body + "</body></html>"; } else { // Find <body> tag and insert our message. var matches = Regex.Match(msg.Body, @"(<body[^<]*>)", RegexOptions.IgnoreCase); if (matches.Success) { var bodyTag = matches.Groups[1].Value; // Insert decryption message. mailItem.HTMLBody = msg.Body.Replace( bodyTag, bodyTag + DecryptAndVerifyHeaderMessage.Replace("\n", "<br />")); } else mailItem.HTMLBody = msg.Body; } } else { // May cause mail item not to open correctly mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatPlain; mailItem.Body = msg.Body; } foreach (SharpAttachment mimeAttachment in msg.Attachments) { mimeAttachment.Stream.Position = 0; var fileName = mimeAttachment.Name; var tempFile = Path.Combine(Path.GetTempPath(), fileName); using (FileStream fout = File.OpenWrite(tempFile)) { mimeAttachment.Stream.CopyTo(fout); } mailItem.Attachments.Add(tempFile, Outlook.OlAttachmentType.olByValue, 1, fileName); } //mailItem.Save(); }
void HandlePgpMime(Outlook.MailItem mailItem, Microsoft.Office.Interop.Outlook.Attachment encryptedMime, Microsoft.Office.Interop.Outlook.Attachment sigMime, string sigHash = "sha1") { logger.Trace("> HandlePgpMime"); CryptoContext Context = null; byte[] cyphertext = null; byte[] clearbytes = null; string cleartext = mailItem.Body; // 1. Decrypt attachement if (encryptedMime != null) { logger.Trace("Decrypting cypher text."); var tempfile = Path.GetTempFileName(); encryptedMime.SaveAsFile(tempfile); cyphertext = File.ReadAllBytes(tempfile); File.Delete(tempfile); clearbytes = DecryptAndVerify(mailItem.To, cyphertext, out Context); if (clearbytes == null) return; cleartext = this._encoding.GetString(clearbytes); } // 2. Verify signature if (sigMime != null) { Context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest); var Crypto = new PgpCrypto(Context); Outlook.OlBodyFormat mailType = mailItem.BodyFormat; try { logger.Trace("Verify detached signature"); var tempfile = Path.GetTempFileName(); sigMime.SaveAsFile(tempfile); var detachedsig = File.ReadAllText(tempfile); File.Delete(tempfile); // Build up a clearsignature format for validation // the rules for are the same with the addition of two heaer fields. // Ultimately we need to get these fields out of email itself. // NOTE: encoding could be uppercase or lowercase. Try both. // this is definetly hacky :/ var encoding = GetEncodingFromMail(mailItem); var clearsigUpper = new StringBuilder(); clearsigUpper.Append(string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\nCharset: {1}\r\n\r\n", sigHash, encoding.BodyName.ToUpper())); clearsigUpper.Append("Content-Type: text/plain; charset="); clearsigUpper.Append(encoding.BodyName.ToUpper()); clearsigUpper.Append("\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n"); clearsigUpper.Append(PgpClearDashEscapeAndQuoteEncode( encoding.GetString( (byte[])mailItem.PropertyAccessor.GetProperty( "http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102")))); clearsigUpper.Append("\r\n"); clearsigUpper.Append(detachedsig); var clearsigLower = new StringBuilder(clearsigUpper.Length); clearsigLower.Append(string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\nCharset: {1}\r\n\r\n", sigHash, encoding.BodyName.ToUpper())); clearsigLower.Append("Content-Type: text/plain; charset="); clearsigLower.Append(encoding.BodyName.ToLower()); clearsigLower.Append("\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n"); clearsigLower.Append(PgpClearDashEscapeAndQuoteEncode( encoding.GetString( (byte[])mailItem.PropertyAccessor.GetProperty( "http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102")))); clearsigLower.Append("\r\n"); clearsigLower.Append(detachedsig); logger.Trace(clearsigUpper.ToString()); if (Crypto.VerifyClear(_encoding.GetBytes(clearsigUpper.ToString())) || Crypto.VerifyClear(_encoding.GetBytes(clearsigLower.ToString()))) { Context = Crypto.Context; var message = "** " + string.Format(Localized.MsgValidSig, Context.SignedByUserId, Context.SignedByKeyId) + "\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) mailItem.Body = message + mailItem.Body; else mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message); } else { Context = Crypto.Context; var message = "** " + string.Format(Localized.MsgInvalidSig, Context.SignedByUserId, Context.SignedByKeyId) + "\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) mailItem.Body = message + mailItem.Body; else mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message); } } catch (PublicKeyNotFoundException ex) { logger.Debug(ex.ToString()); Context = Crypto.Context; var message = "** " + Localized.MsgSigMissingPubKey + "\n\n"; if (mailType == Outlook.OlBodyFormat.olFormatPlain) mailItem.Body = message + mailItem.Body; else mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message); } catch (Exception ex) { logger.Debug(ex.ToString()); WriteErrorData("VerifyEmail", ex); MessageBox.Show( ex.Message, "Outlook Privacy Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } if (Context == null) return; // Extract files from MIME data MimeMessage msg = null; TextPart textPart = null; MimeEntity htmlPart = null; var isHtml = false; using(var sin = new MemoryStream(clearbytes)) { var parser = new MimeParser(sin); msg = parser.ParseMessage(); var iter = new MimeIterator(msg); while(iter.MoveNext()) { var part = iter.Current as TextPart; if (part == null) continue; if (part.IsAttachment) continue; // message could include both text and html // if we find html use that over text. if (part.IsHtml) { htmlPart = part; isHtml = true; } else { textPart = part; } } } var DecryptAndVerifyHeaderMessage = "** "; if (Context.IsEncrypted) DecryptAndVerifyHeaderMessage += Localized.MsgDecrypt + " "; if (Context.FailedIntegrityCheck) DecryptAndVerifyHeaderMessage += Localized.MsgFailedIntegrityCheck + " "; if (Context.IsSigned && Context.SignatureValidated) { DecryptAndVerifyHeaderMessage += string.Format(Localized.MsgValidSig, Context.SignedByUserId, Context.SignedByKeyId); } else if (Context.IsSigned) { DecryptAndVerifyHeaderMessage += string.Format(Localized.MsgInvalidSig, Context.SignedByUserId, Context.SignedByKeyId); } else DecryptAndVerifyHeaderMessage += Localized.MsgUnsigned; DecryptAndVerifyHeaderMessage += "\n\n"; if(isHtml) { var htmlBody = msg.HtmlBody; var related = msg.Body as MultipartRelated; var doc = new HtmlAgilityPack.HtmlDocument(); var savedImages = new List<MimePart>(); doc.LoadHtml(htmlBody); // Find any embedded images foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]")) { var src = img.Attributes["src"]; 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) string imageCid = src.Value.Substring(4); var iter = new MimeIterator(msg); MimePart attachment = null; while (iter.MoveNext()) { if (iter.Current.ContentId == imageCid) { attachment = iter.Current as MimePart; break; } } if (attachment == null) continue; string fileName; // save the attachment (if we haven't already saved it) if (!savedImages.Contains(attachment)) { fileName = attachment.FileName; if (string.IsNullOrEmpty(fileName)) fileName = Guid.NewGuid().ToString(); using (var stream = File.Create(fileName)) attachment.ContentObject.DecodeTo(stream); try { var att = mailItem.Attachments.Add(fileName, Outlook.OlAttachmentType.olEmbeddeditem, null, ""); att.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageCid); savedImages.Add(attachment); } finally { // try not to leak temp files :) File.Delete(fileName); } } } mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML; mailItem.HTMLBody = AddMessageToHtmlBody(htmlBody, DecryptAndVerifyHeaderMessage); } else { // NOTE: For some reason we cannot change the BodyFormat once it's set. // So if we are set to HTML we need to wrap the plain text so it's // displayed okay. Also of course prevent XSS. if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = DecryptAndVerifyHeaderMessage + msg.TextBody; } else { var sb = new StringBuilder(msg.TextBody.Length + 100); sb.Append("<html><body><pre>"); sb.Append(System.Net.WebUtility.HtmlEncode(DecryptAndVerifyHeaderMessage)); sb.Append(System.Net.WebUtility.HtmlEncode(msg.TextBody)); sb.Append("</pre></body></html>"); mailItem.HTMLBody = sb.ToString(); } } // NOTE: Removing existing attachments is perminant, even if the message // is not saved. foreach (var mimeAttachment in msg.Attachments) { var fileName = mimeAttachment.FileName; var tempFile = Path.Combine(Path.GetTempPath(), fileName); using (FileStream fout = File.OpenWrite(tempFile)) { mimeAttachment.ContentObject.DecodeTo(fout); } mailItem.Attachments.Add(tempFile, Outlook.OlAttachmentType.olByValue, 1, fileName); File.Delete(tempFile); } }
/* Upload attachments */ public void attachFile(Microsoft.Office.Interop.Outlook.Attachment attachment, string docRef) { // Save attachments in local string fsFilename = repTemp + attachment.FileName; attachment.SaveAsFile(fsFilename); EnvoiPJ(attachment.FileName, fsFilename, docRef); }
void HandlePgpMime(Outlook.MailItem mailItem, Microsoft.Office.Interop.Outlook.Attachment encryptedMime) { // 1. Decrypt attachement CryptoContext Context; var tempfile = Path.GetTempFileName(); encryptedMime.SaveAsFile(tempfile); var encrypteddata = File.ReadAllBytes(tempfile); var cleardata = DecryptAndVerify(mailItem.To, encrypteddata, out Context); if (cleardata == null) return; // Extract files from MIME data SharpMessage msg = new SharpMessage(this._encoding.GetString(cleardata)); string body = mailItem.Body; var DecryptAndVerifyHeaderMessage = "** "; if (Context.IsEncrypted) DecryptAndVerifyHeaderMessage += "Message decrypted. "; if (Context.IsSigned && Context.SignatureValidated) { DecryptAndVerifyHeaderMessage += "Valid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId; } else if (Context.IsSigned) { DecryptAndVerifyHeaderMessage += "Invalid signature from \"" + Context.SignedByUserId + "\" with KeyId " + Context.SignedByKeyId + "."; } else DecryptAndVerifyHeaderMessage += "Message was unsigned."; DecryptAndVerifyHeaderMessage += "\n\n"; if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain) { mailItem.Body = DecryptAndVerifyHeaderMessage + msg.Body; } else if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatHTML) { if (!msg.Body.TrimStart().ToLower().StartsWith("<html")) { body = DecryptAndVerifyHeaderMessage + msg.Body; body = System.Net.WebUtility.HtmlEncode(body); body = body.Replace("\n", "<br />"); mailItem.HTMLBody = "<html><head></head><body>" + body + "</body></html>"; } else { // Find <body> tag and insert our message. var matches = Regex.Match(msg.Body, @"(<body[^<]*>)", RegexOptions.IgnoreCase); if (matches.Success) { var bodyTag = matches.Groups[1].Value; // Insert decryption message. mailItem.HTMLBody = msg.Body.Replace( bodyTag, bodyTag + DecryptAndVerifyHeaderMessage.Replace("\n", "<br />")); } else mailItem.HTMLBody = msg.Body; } } else { // May cause mail item not to open correctly mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatPlain; mailItem.Body = msg.Body; } foreach (SharpAttachment mimeAttachment in msg.Attachments) { mimeAttachment.Stream.Position = 0; var fileName = mimeAttachment.Name; var tempFile = Path.Combine(Path.GetTempPath(), fileName); using (FileStream fout = File.OpenWrite(tempFile)) { mimeAttachment.Stream.CopyTo(fout); } mailItem.Attachments.Add(tempFile, Outlook.OlAttachmentType.olByValue, 1, fileName); } //mailItem.Save(); }