Merge with default OUT-366. S/MIME
authornikolaj
Tue, 06 Mar 2018 14:40:46 +0100
branchOUT-366. S/MIME
changeset 2041c8101fab710e
parent 2018 36740325c1e1
parent 2040 94ef905b1764
Merge with default
Extensions/MailItemExtensions.cs
ThisAddIn.cs
     1.1 --- a/AdapterExtensions.cs	Tue Feb 20 17:07:50 2018 +0100
     1.2 +++ b/AdapterExtensions.cs	Tue Mar 06 14:40:46 2018 +0100
     1.3 @@ -80,7 +80,6 @@
     1.4                      {
     1.5                          rating = ThisAddIn.PEPEngine.ReEvaluateMessageRating(src, keyList, rating);
     1.6                      }
     1.7 -
     1.8                  }
     1.9                  catch (Exception ex)
    1.10                  {
     2.1 --- a/CryptableMailItem.cs	Tue Feb 20 17:07:50 2018 +0100
     2.2 +++ b/CryptableMailItem.cs	Tue Mar 06 14:40:46 2018 +0100
     2.3 @@ -114,19 +114,22 @@
     2.4          /* Stores the message id of an attached mail item if it is loaded into the preview. 
     2.5           * See comments below in MailItem_BeforeAttachmentPreview event handler.
     2.6           */
     2.7 -        public static string                      PreviewAttachedMailId = null;
     2.8 +        public static string    PreviewAttachedMailId = null;
     2.9  
    2.10          // Whether to cancel the opening event of the internal mail item. Default is false.
    2.11 -        public bool         CancelOpen      { get; set; } = false;
    2.12 +        public bool         CancelOpen              { get; set; } = false;
    2.13  
    2.14          // The messageId of the internal mail item. Only needed for special cases like attached mails.
    2.15 -        public string       MessageId       { get; set; } = null;
    2.16 +        public string       MessageId               { get; set; } = null;
    2.17  
    2.18          // Whether the internal mail item is an attached mail
    2.19 -        public bool         IsSecureAttachedMail  { get; set; } = false;
    2.20 +        public bool         IsSecureAttachedMail    { get; set; } = false;
    2.21  
    2.22 -        // The mirror of the internal mail item stored as PEPMessage.
    2.23 -        public PEPMessage   Mirror          { get; set; } = null;
    2.24 +        // The mirror of the internal mail item stored as PEPMessage
    2.25 +        public PEPMessage   Mirror                  { get; set; } = null;
    2.26 +
    2.27 +        // The PEPMessage of this mail item
    2.28 +        public PEPMessage   Message                 { get; set; } = null;
    2.29  
    2.30          /**************************************************************
    2.31           * 
    2.32 @@ -1266,6 +1269,7 @@
    2.33                          if (PEPMessage.Create(this.internalMailItem, out mirror) == Globals.ReturnStatus.Success)
    2.34                          {
    2.35                              result = AdapterExtensions.ReevaluateMessageRating(mirror);
    2.36 +                            this.Message = mirror;
    2.37                          }
    2.38                      }
    2.39                      catch (Exception ex)
    2.40 @@ -1365,11 +1369,10 @@
    2.41                       * FormRegionPreviewUnencrypted to be shown in Outlook 2010 (technically, all versions require this according to the documentation).
    2.42                       * See: https://msdn.microsoft.com/en-us/library/office/ff866019.aspx
    2.43                       * In case of Outlook 2010, set message class for all messages in secure stores, as this version often downloads only mail headers in the first place
    2.44 -                     * which then leads to the form region not being properly dispayed at the first click (OUT-68).
    2.45 +                     * which then leads to the form region not being properly displayed at the first click (OUT-68).
    2.46                       */
    2.47                      if ((isPEPInternal == false) &&
    2.48 -                         (isSecurelyStored ||
    2.49 -                         (Globals.GetOutlookVersion() == Globals.Version.Outlook2010 && this.internalMailItem.GetIsInSecureStore() && this.internalMailItem.DownloadState == Outlook.OlDownloadState.olHeaderOnly)))
    2.50 +                         (Globals.GetOutlookVersion() == Globals.Version.Outlook2010 && this.internalMailItem.GetIsInSecureStore() && this.internalMailItem.DownloadState == Outlook.OlDownloadState.olHeaderOnly))
    2.51                      {
    2.52                          try
    2.53                          {
    2.54 @@ -1580,6 +1583,7 @@
    2.55                          }
    2.56                      }
    2.57  
    2.58 +                    this.Message = processedMessage ?? message;
    2.59                      result = processedRating;
    2.60                  }
    2.61  
    2.62 @@ -1724,23 +1728,29 @@
    2.63  
    2.64              try
    2.65              {
    2.66 -                lock (mutexMailItem)
    2.67 +                if (this.Mirror != null)
    2.68                  {
    2.69 -                    string id = e.Argument as string;
    2.70 -                    omi = this.internalMailItem.GetMirror(id);
    2.71 +                    // If we already have a mirror, use it
    2.72 +                    e.Result = this.Mirror;
    2.73 +                }
    2.74 +                else
    2.75 +                {
    2.76 +                    // If no stored mirror is there, look it up
    2.77 +                    lock (mutexMailItem)
    2.78 +                    {
    2.79 +                        string id = e.Argument as string;
    2.80 +                        omi = this.internalMailItem.GetMirror(id);
    2.81  
    2.82 -                    if (omi != null)
    2.83 -                    {
    2.84 -                        Log.Verbose("MirrorLocator_DoWork: Mirror found");
    2.85 +                        if (omi != null)
    2.86 +                        {
    2.87 +                            Log.Verbose("MirrorLocator_DoWork: Mirror found");
    2.88  
    2.89 -                        sts = PEPMessage.Create(omi, out mirror);
    2.90 +                            sts = PEPMessage.Create(omi, out mirror);
    2.91 +                        }
    2.92 +                    }
    2.93  
    2.94 -                        // Marshal.ReleaseComObject(omi);
    2.95 -                        omi = null;
    2.96 -                    }
    2.97 +                    e.Result = mirror;
    2.98                  }
    2.99 -
   2.100 -                e.Result = mirror;
   2.101              }
   2.102              catch (Exception ex)
   2.103              {
   2.104 @@ -1748,16 +1758,10 @@
   2.105              }
   2.106              finally
   2.107              {
   2.108 -                if (omi != null)
   2.109 -                {
   2.110 -                    // Marshal.ReleaseComObject(omi);
   2.111 -                    omi = null;
   2.112 -                }
   2.113 +                omi = null;
   2.114              }
   2.115  
   2.116              Log.Verbose("MirrorLocator_DoWork: Completed");
   2.117 -
   2.118 -            return;
   2.119          }
   2.120  
   2.121          /// <summary>
     3.1 --- a/DecryptionStack.cs	Tue Feb 20 17:07:50 2018 +0100
     3.2 +++ b/DecryptionStack.cs	Tue Mar 06 14:40:46 2018 +0100
     3.3 @@ -244,7 +244,7 @@
     3.4                       * handshake dialog, which has to happen from the main thread. The constructors of those 
     3.5                       * dialogs cannot be called from the background worker. 
     3.6                       */ 
     3.7 -                    if (omi.GetIsForceFullyProtected())
     3.8 +                    if (omi.GetIsForcefullyProtected())
     3.9                      {
    3.10                          Log.Verbose("DecryptionStack.DecryptionTimer_Tick: Force Protection Protocol Message found. Processing...");
    3.11                          var fppMessage = new FPPMessage(omi);
     4.1 --- a/Extensions/MailItemExtensions.cs	Tue Feb 20 17:07:50 2018 +0100
     4.2 +++ b/Extensions/MailItemExtensions.cs	Tue Mar 06 14:40:46 2018 +0100
     4.3 @@ -108,7 +108,7 @@
     4.4          /// </summary>
     4.5          /// <param name="omi">The Outlook mail item to process with.</param>
     4.6          /// <returns>True if the Outlook mail item is marked to force protection, otherwise false.</returns>
     4.7 -        public static bool GetIsForceFullyProtected(this Outlook.MailItem omi)
     4.8 +        public static bool GetIsForcefullyProtected(this Outlook.MailItem omi)
     4.9          {
    4.10              string forceProtectionId = omi.GetForceProtectionId();
    4.11  
    4.12 @@ -1292,7 +1292,7 @@
    4.13              if (omi != null)
    4.14              {
    4.15                  if ((omi.GetNeverUnsecure() && (omi.GetIsMirror() == false)) ||
    4.16 -                    (omi.GetIsInSecureStore() && (omi.GetIsSecure() || omi.GetIsForceFullyProtected())))
    4.17 +                    (omi.GetIsInSecureStore() && (omi.GetIsSecure() || omi.GetIsForcefullyProtected())))
    4.18                  {
    4.19                      return (true);
    4.20                  }
    4.21 @@ -1319,7 +1319,7 @@
    4.22                      // If pEp is disabled, process in case of ForceProtected or EnableProtection
    4.23                      if (omi.GetIsPEPEnabled() == false)
    4.24                      {
    4.25 -                        isEnabled = (omi.GetIsForceFullyProtected() || omi.GetEnableProtection());
    4.26 +                        isEnabled = (omi.GetIsForcefullyProtected() || omi.GetEnableProtection());
    4.27                      }
    4.28                  }
    4.29                  catch (Exception ex)
    4.30 @@ -2085,7 +2085,7 @@
    4.31              }
    4.32  
    4.33              // If mail is forcefully protected, return reliable
    4.34 -            if (omi?.GetIsForceFullyProtected() == true)
    4.35 +            if (omi?.GetIsForcefullyProtected() == true)
    4.36              {
    4.37                  return pEpRating.pEpRatingReliable;
    4.38              }
     5.1 --- a/FPPMessage.cs	Tue Feb 20 17:07:50 2018 +0100
     5.2 +++ b/FPPMessage.cs	Tue Mar 06 14:40:46 2018 +0100
     5.3 @@ -199,7 +199,7 @@
     5.4                  string[] keyList;
     5.5                  pEpDecryptFlags flags;
     5.6  
     5.7 -                // Decryt incoming message
     5.8 +                // Decrypt incoming message
     5.9                  MsgProcessor msgProcessor = new MsgProcessor();
    5.10                  if (msgProcessor.Decrypt(this.CurrentMessage, out processedMessage, out keyList, out flags, out processedRating) == false)
    5.11                  {
    5.12 @@ -214,7 +214,7 @@
    5.13                          this.CurrentMessage = processedMessage;
    5.14                      }
    5.15  
    5.16 -                    // Set rating to reliable if processed rating is the exptected one (unencrypted)
    5.17 +                    // Set rating to reliable if processed rating is the expected one (unencrypted)
    5.18                      this.CurrentMessage.Rating = (processedRating == pEpRating.pEpRatingUnencrypted) ? pEpRating.pEpRatingReliable : processedRating;
    5.19  
    5.20                      return Globals.ReturnStatus.Success;
    5.21 @@ -577,9 +577,11 @@
    5.22          /// <returns>The status of this method.</returns>
    5.23          public Globals.ReturnStatus DecryptMessage(string entryId, string key)
    5.24          {
    5.25 +            bool isSecurelyStored = false;
    5.26              string filePath = null;
    5.27              string decryptedFilePath = null;
    5.28              Outlook.MailItem omi = null;
    5.29 +            Outlook.MailItem mirror = null;
    5.30              Outlook.Attachments attachments = null;
    5.31              Outlook.Attachment attachment = null;
    5.32              PEPMessage decryptedMessage = null;
    5.33 @@ -627,93 +629,116 @@
    5.34                          throw new Exception("Encrypted attachment not found.");
    5.35                      }
    5.36  
    5.37 -                    // Save attachment on disk
    5.38 -                    filePath = Path.GetTempPath() + attachment.FileName;
    5.39 -                    attachment.SaveAsFile(filePath);
    5.40 +                    // Check if message is in secure store or never unsecure
    5.41 +                    isSecurelyStored = (omi.GetNeverUnsecure() || omi.GetIsInSecureStore());
    5.42  
    5.43 -                    // Create file name for decrypted message and make sure it doesn't exist yet
    5.44 -                    decryptedFilePath = Path.ChangeExtension(filePath, "eml");
    5.45 -                    int counter = 1;
    5.46 -                    while (File.Exists(decryptedFilePath))
    5.47 +                    // If securely stored, look up mirror
    5.48 +                    if (isSecurelyStored)
    5.49                      {
    5.50 -                        decryptedFilePath = decryptedFilePath.Replace(".eml", (counter++ + ".eml"));
    5.51 +                        mirror = omi.GetMirror();
    5.52                      }
    5.53  
    5.54 -                    // Decrypt message
    5.55 -                    if (FPPMessage.DecryptFile(filePath, decryptedFilePath, key) != Globals.ReturnStatus.Success)
    5.56 +                    // If not securely stored or no mirror has been found, decrypt
    5.57 +                    if (mirror == null)
    5.58                      {
    5.59 -                        throw new Exception("DecryptMessage: Error decrypting message.");
    5.60 -                    }
    5.61 +                        // Save attachment on disk
    5.62 +                        filePath = Path.GetTempPath() + attachment.FileName;
    5.63 +                        attachment.SaveAsFile(filePath);
    5.64  
    5.65 -                    // Load decrypted eml file and apply it to Outlook mail item
    5.66 -                    MimeMessage message = MimeMessage.Load(decryptedFilePath);
    5.67 +                        // Create file name for decrypted message and make sure it doesn't exist yet
    5.68 +                        decryptedFilePath = Path.ChangeExtension(filePath, "eml");
    5.69 +                        int counter = 1;
    5.70 +                        while (File.Exists(decryptedFilePath))
    5.71 +                        {
    5.72 +                            decryptedFilePath = decryptedFilePath.Replace(".eml", (counter++ + ".eml"));
    5.73 +                        }
    5.74  
    5.75 -                    if (PEPMessage.Create(message, out decryptedMessage) == Globals.ReturnStatus.Success)
    5.76 -                    {
    5.77 -                        // Delete the Force Protection property
    5.78 -                        decryptedMessage.ForceProtectionId = null;
    5.79 +                        // Decrypt message
    5.80 +                        if (FPPMessage.DecryptFile(filePath, decryptedFilePath, key) != Globals.ReturnStatus.Success)
    5.81 +                        {
    5.82 +                            throw new Exception("DecryptMessage: Error decrypting message.");
    5.83 +                        }
    5.84  
    5.85 -                        // Set rating to reliable
    5.86 -                        decryptedMessage.Rating = pEpRating.pEpRatingReliable;
    5.87 +                        // Load decrypted eml file and apply it to Outlook mail item
    5.88 +                        MimeMessage message = MimeMessage.Load(decryptedFilePath);
    5.89  
    5.90 -                        // Add the sender's fingerprint to the message's key list
    5.91 -                        try
    5.92 +                        if (PEPMessage.Create(message, out decryptedMessage) == Globals.ReturnStatus.Success)
    5.93                          {
    5.94 -                            var ident = ThisAddIn.PEPEngine.UpdateIdentity(decryptedMessage.From.ToCOMType());
    5.95 -                            var keyList = decryptedMessage.KeyList;
    5.96 -                            if (string.IsNullOrEmpty(keyList))
    5.97 +                            // Delete the Force Protection property
    5.98 +                            decryptedMessage.ForceProtectionId = null;
    5.99 +
   5.100 +                            // Set rating to reliable
   5.101 +                            decryptedMessage.Rating = pEpRating.pEpRatingReliable;
   5.102 +
   5.103 +                            // Add the sender's fingerprint to the message's key list
   5.104 +                            try
   5.105                              {
   5.106 -                                keyList = ident.fpr;
   5.107 +                                var ident = ThisAddIn.PEPEngine.UpdateIdentity(decryptedMessage.From.ToCOMType());
   5.108 +                                var keyList = decryptedMessage.KeyList;
   5.109 +                                if (string.IsNullOrEmpty(keyList))
   5.110 +                                {
   5.111 +                                    keyList = ident.fpr;
   5.112 +                                }
   5.113 +                                else
   5.114 +                                {
   5.115 +                                    keyList = keyList.Insert(0, (ident.fpr + ","));
   5.116 +                                }
   5.117 +                                decryptedMessage.KeyList = keyList;
   5.118 +                            }
   5.119 +                            catch (Exception ex)
   5.120 +                            {
   5.121 +                                Log.Error("DecryptMessage: Error adding key list to message. " + ex.ToString());
   5.122 +                            }
   5.123 +
   5.124 +                            // If message was created correctly, apply it
   5.125 +                            if (isSecurelyStored)
   5.126 +                            {
   5.127 +                                // For untrusted server, set rating
   5.128 +                                omi.SetPEPProperty(MailItemExtensions.PEPProperty.Rating, pEpRating.pEpRatingReliable);
   5.129 +                                omi.Save();
   5.130 +
   5.131 +                                // Create a mirror and apply the decrypted message
   5.132 +                                Outlook.MailItem item = omi.CreateMirrorOMI();
   5.133 +                                decryptedMessage.ApplyTo(item, true, false);
   5.134 +                                item.Save();
   5.135 +                                item = null;
   5.136                              }
   5.137                              else
   5.138                              {
   5.139 -                                keyList = keyList.Insert(0, (ident.fpr + ","));
   5.140 +                                // For trusted server, apply decrypted message to original
   5.141 +                                decryptedMessage.ApplyTo(omi, true, false);
   5.142 +                                omi.Save();
   5.143                              }
   5.144 -                            decryptedMessage.KeyList = keyList;
   5.145                          }
   5.146 -                        catch (Exception ex)
   5.147 +                    }
   5.148 +
   5.149 +                    if (isSecurelyStored)
   5.150 +                    {
   5.151 +                        // Update the UI with the decrypted message
   5.152 +                        WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveWindow()];
   5.153 +
   5.154 +                        if (formRegions?.FormRegionPreviewUnencrypted?.Visible == true)
   5.155                          {
   5.156 -                            Log.Error("DecryptMessage: Error adding key list to message. " + ex.ToString());
   5.157 -                        }
   5.158 -
   5.159 -                        // If message was created correctly, apply it
   5.160 -                        if (omi.GetIsSecurelyStored())
   5.161 -                        {
   5.162 -                            // For untrusted server / never unsecure, delete FPP property from original and set rating
   5.163 -                            omi.SetPEPProperty(MailItemExtensions.PEPProperty.ForceProtection, null);
   5.164 -                            omi.SetPEPProperty(MailItemExtensions.PEPProperty.Rating, pEpRating.pEpRatingReliable);
   5.165 -                            omi.Save();
   5.166 -
   5.167 -                            // Create a mirror and apply the decrypted message
   5.168 -                            Outlook.MailItem item = omi.CreateMirrorOMI();
   5.169 -                            decryptedMessage.ApplyTo(item, true, false);
   5.170 -                            item.Save();
   5.171 -                            item = null;
   5.172 -
   5.173 -                            // Update the UI with the decrypted message
   5.174 -                            WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveWindow()];
   5.175 -
   5.176 -                            if (formRegions?.FormRegionPreviewUnencrypted?.Visible == true)
   5.177 +                            // If we don't have a decrypted PEPMessage yet, create it
   5.178 +                            if ((decryptedMessage == null) &&
   5.179 +                                PEPMessage.Create(mirror, out decryptedMessage) != Globals.ReturnStatus.Success)
   5.180                              {
   5.181 -                                formRegions.FormRegionPreviewUnencrypted.DisplayState.SetMessage(decryptedMessage);
   5.182 -                                Log.Verbose("DecryptMessage: Mirror created and displayed.");
   5.183 -                            }
   5.184 -                            else
   5.185 -                            {
   5.186 -                                Log.Verbose("DecryptMessage: Error displaying mirror.");
   5.187 +                                throw new Exception("Error creating PEPMessage from mirror");
   5.188                              }
   5.189  
   5.190 -                            formRegions.FormRegionPrivacyStatus?.UpdateFormRegion(true);
   5.191 +                            // Show mirror
   5.192 +                            formRegions.FormRegionPreviewUnencrypted.DisplayState.SetMessage(decryptedMessage);
   5.193 +                            Log.Verbose("DecryptMessage: Mirror created and displayed.");
   5.194                          }
   5.195                          else
   5.196                          {
   5.197 -                            // For trusted server, apply decrypted message to original
   5.198 -                            decryptedMessage.ApplyTo(omi, true, false);
   5.199 -                            omi.Save();
   5.200 +                            Log.Verbose("DecryptMessage: FormRegionPreviewUnencrypted not visible.");
   5.201                          }
   5.202  
   5.203 -                        status = Globals.ReturnStatus.Success;
   5.204 +                        formRegions.FormRegionPrivacyStatus?.UpdateFormRegion(true);
   5.205                      }
   5.206 +
   5.207 +                    status = Globals.ReturnStatus.Success;
   5.208                  }
   5.209                  catch (Exception ex)
   5.210                  {
   5.211 @@ -724,6 +749,7 @@
   5.212                      attachment = null;
   5.213                      attachments = null;
   5.214                      omi = null;
   5.215 +                    mirror = null;
   5.216                  }
   5.217  
   5.218                  // Delete the attachment file
     6.1 --- a/MsgProcessor.cs	Tue Feb 20 17:07:50 2018 +0100
     6.2 +++ b/MsgProcessor.cs	Tue Mar 06 14:40:46 2018 +0100
     6.3 @@ -716,12 +716,13 @@
     6.4                      result = this.Encrypt(encryptedMessages[i], extraKeys, out newMessage);
     6.5                      encryptedMessages[i] = newMessage;
     6.6  
     6.7 -                    // Check to ensure the message was really encrypted
     6.8 -                    // This is just a double check against presenting the user with one rating, but actually delivering another.
     6.9 -                    // If this happens, an error occured elsewhere, likely in the engine
    6.10 +                    /* Check to ensure the message was really encrypted.
    6.11 +                     * This is just a double check against presenting the user with one rating, but actually delivering another.
    6.12 +                     * If message is unencrypted (and no forcefully encrypted message), an error occured elsewhere, likely in the engine.
    6.13 +                     */
    6.14                      if ((result == false) ||
    6.15                          ((outgoingRating >= pEpRating.pEpRatingReliable) &&
    6.16 -                         (newMessage.IsSecure == false)))
    6.17 +                         ((newMessage.IsSecure == false) && string.IsNullOrEmpty(newMessage.ForceProtectionId))))
    6.18                      {
    6.19                          status = Globals.ReturnStatus.Failure;
    6.20                          Log.Error("ProcessSentMessage: Message encryption failed or doesn't match outgoing rating.");
    6.21 @@ -951,7 +952,7 @@
    6.22                  keyList = new string[0];
    6.23              }
    6.24  
    6.25 -            Log.Verbose("Decrypt: Complete. " + sourceMessage?.Id);
    6.26 +            Log.SensitiveData("Decrypt: Complete. " + sourceMessage?.Id);
    6.27  
    6.28              return rating;
    6.29          }
     7.1 --- a/PEPMessage.cs	Tue Feb 20 17:07:50 2018 +0100
     7.2 +++ b/PEPMessage.cs	Tue Mar 06 14:40:46 2018 +0100
     7.3 @@ -27,7 +27,7 @@
     7.4          public const string PR_ENC_STATUS_NAME           = "X-EncStatus";
     7.5          public const string PR_KEY_LIST_NAME             = "X-KeyList";
     7.6          public const string PR_PEP_AUTO_CONSUME_NAME     = "pEp-auto-consume";
     7.7 -        public const string PR_PEP_FORCE_PROTECTION_NAME = "pEp-force-protection";
     7.8 +        public const string PR_PEP_FORCE_PROTECTION_NAME = "X-pEp-force-protection";
     7.9          public const string PR_PEP_NEVER_UNSECURE_NAME   = "X-pEp-Never-Unsecure";
    7.10          public const string PR_PEP_PROTOCOL_VERSION_NAME = "X-pEp-Version";
    7.11  
    7.12 @@ -610,7 +610,7 @@
    7.13              }
    7.14          }
    7.15  
    7.16 -#endregion
    7.17 +        #endregion
    7.18  
    7.19          /**************************************************************
    7.20           * 
    7.21 @@ -1182,7 +1182,7 @@
    7.22              copy.ConversationTopic = (this._ConversationTopic == null ? null : string.Copy(this._ConversationTopic));
    7.23              copy.Direction = this._Direction;
    7.24              copy.EnableProtection = this._EnableProtection;
    7.25 -            copy.ForceProtectionId = this._ForceProtectionId;
    7.26 +            copy.ForceProtectionId = (this._ForceProtectionId == null ? null : string.Copy(this._ForceProtectionId));
    7.27              copy.ForceUnencrypted = this._ForceUnencrypted;
    7.28              copy.From = (this._From == null ? null : this._From.Copy());
    7.29              copy.Id = (this._Id == null ? null : string.Copy(this._Id));
    7.30 @@ -1931,6 +1931,20 @@
    7.31                  omi.SetPEPProperty(MailItemExtensions.PEPProperty.ForceProtection, this._ForceProtectionId);
    7.32                  omi.SetPEPProperty(MailItemExtensions.PEPProperty.NeverUnsecure, this._NeverUnsecure);
    7.33                  omi.SetPEPProperty(MailItemExtensions.PEPProperty.PEPProtocolVersion, this._PEPProtocolVersion);
    7.34 +
    7.35 +                // Cancel ReadReceiptRequested and OriginatorDeliveryReportRequested for automatic mails
    7.36 +                if (string.IsNullOrEmpty(this.AutoConsume) == false)
    7.37 +                {
    7.38 +                    try
    7.39 +                    {
    7.40 +                        omi.ReadReceiptRequested = false;
    7.41 +                        omi.OriginatorDeliveryReportRequested = false;
    7.42 +                    }
    7.43 +                    catch (Exception ex)
    7.44 +                    {
    7.45 +                        Log.Error("PEPMessage.ApplyTo: Error cancelling ReadReceiptRequested and OriginatorDeliveryReportRequested: " + ex.ToString());
    7.46 +                    }
    7.47 +                }
    7.48              }
    7.49              catch (Exception ex)
    7.50              {
     8.1 --- a/Properties/AssemblyInfo.cs	Tue Feb 20 17:07:50 2018 +0100
     8.2 +++ b/Properties/AssemblyInfo.cs	Tue Mar 06 14:40:46 2018 +0100
     8.3 @@ -43,5 +43,5 @@
     8.4  // You can specify all the values or you can default the Build and Revision Numbers 
     8.5  // by using the '*' as shown below:
     8.6  // [assembly: AssemblyVersion("1.0.*")]
     8.7 -[assembly: AssemblyVersion("1.1.30.0")]
     8.8 -[assembly: AssemblyFileVersion("1.1.30.0")]
     8.9 +[assembly: AssemblyVersion("1.0.90.0")]
    8.10 +[assembly: AssemblyFileVersion("1.0.90.0")]
     9.1 --- a/ThisAddIn.cs	Tue Feb 20 17:07:50 2018 +0100
     9.2 +++ b/ThisAddIn.cs	Tue Mar 06 14:40:46 2018 +0100
     9.3 @@ -3288,7 +3288,7 @@
     9.4                  {
     9.5                      // If ForceProtected, create special mail
     9.6                      bool processMessage = true;
     9.7 -                    bool isForceFullyProtected = (omi?.GetIsForceFullyProtected() == true);
     9.8 +                    bool isForceFullyProtected = (omi?.GetIsForcefullyProtected() == true);
     9.9                      if (isForceFullyProtected)
    9.10                      {
    9.11                          Log.Info("Sending forcefully protected message.");
    10.1 --- a/UI/FormControlPreviewMessage.xaml.cs	Tue Feb 20 17:07:50 2018 +0100
    10.2 +++ b/UI/FormControlPreviewMessage.xaml.cs	Tue Mar 06 14:40:46 2018 +0100
    10.3 @@ -12,6 +12,7 @@
    10.4  using System.Linq;
    10.5  using System.Windows.Media.Imaging;
    10.6  using Outlook = Microsoft.Office.Interop.Outlook;
    10.7 +using Word = Microsoft.Office.Interop.Word;
    10.8  
    10.9  namespace pEp.UI
   10.10  {
   10.11 @@ -189,15 +190,51 @@
   10.12                          if (mirror != null)
   10.13                          {
   10.14                              try
   10.15 -                            {
   10.16 -                                // Save mirror in RTF format in local user Temp folder
   10.17 +                            {                                
   10.18                                  string mirrorRtfTempFilePath = Path.GetTempFileName();
   10.19 +                                string mirrorMhtTempFilePath = Path.GetTempFileName();
   10.20 +                                string mirrorRtfTempFilePathFromOutlook = Path.GetTempFileName();
   10.21                                  mirror.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
   10.22 -                                mirror.SaveAs(mirrorRtfTempFilePath, Outlook.OlSaveAsType.olRTF);
   10.23 +                                                                
   10.24 +                                // Save mirror as MHT and resave as RTF using WORD
   10.25 +                                bool wordFileSaved = false;
   10.26 +                                try
   10.27 +                                {
   10.28 +                                    // Saving mirror as MHT
   10.29 +                                    mirror.SaveAs(mirrorMhtTempFilePath, Outlook.OlSaveAsType.olMHTML);
   10.30  
   10.31 -                                // Load mirror file into the UI
   10.32 -                                this.RichTextBoxMessageBody.LoadFile(mirrorRtfTempFilePath, System.Windows.Forms.RichTextBoxStreamType.RichText);
   10.33 +                                    // Save as RTF using WORD
   10.34 +                                    Word.Application wordAp = new Word.Application();                                    
   10.35 +                                    if (wordAp != null)
   10.36 +                                    {
   10.37 +                                        wordAp.Visible = false;
   10.38 +                                        Word.Document wordDocument = wordAp.Documents.Open(mirrorMhtTempFilePath);
   10.39 +                                        wordDocument.SaveAs2(mirrorRtfTempFilePath, Word.WdSaveFormat.wdFormatRTF);
   10.40 +                                        wordDocument.Close();
   10.41 +                                        wordAp.Quit();
   10.42 +                                        wordFileSaved = true;
   10.43 +                                    }                                    
   10.44 +                                }
   10.45 +                                catch(Exception ex)
   10.46 +                                {
   10.47 +                                    Log.Error("SetRichTextBoxContent: Error during saving mirror using WORD: " + ex.ToString());
   10.48 +                                }
   10.49  
   10.50 +                                if (wordFileSaved)
   10.51 +                                {
   10.52 +                                    // Load mirror file into the UI
   10.53 +                                    this.RichTextBoxMessageBody.LoadFile(mirrorRtfTempFilePath, System.Windows.Forms.RichTextBoxStreamType.RichText);
   10.54 +                                }
   10.55 +                                else
   10.56 +                                {
   10.57 +                                    // Save mirror in RTF format in local user Temp folder                                 
   10.58 +                                    mirror.SaveAs(mirrorRtfTempFilePathFromOutlook, Outlook.OlSaveAsType.olRTF);
   10.59 +                                    // Load mirror file into the UI
   10.60 +                                    this.RichTextBoxMessageBody.LoadFile(mirrorRtfTempFilePathFromOutlook, System.Windows.Forms.RichTextBoxStreamType.RichText);
   10.61 +                                }
   10.62 +                                
   10.63 +
   10.64 +                                
   10.65                                  // Delete lines with fields "From", "OrigEntryId" and others                                                             
   10.66                                  int origEntryId = this.RichTextBoxMessageBody.Find(MailItemExtensions.USER_PROPERTY_KEY_ORIG_ENTRY_ID + ":");
   10.67                                  if (origEntryId > 1)
   10.68 @@ -215,6 +252,8 @@
   10.69  
   10.70                                  // Delete Temp file
   10.71                                  File.Delete(mirrorRtfTempFilePath);
   10.72 +                                File.Delete(mirrorRtfTempFilePath);
   10.73 +                                File.Delete(mirrorRtfTempFilePathFromOutlook);                                
   10.74  
   10.75                                  // Set flag to indicate that content has been displayed successfully
   10.76                                  success = true;
    11.1 --- a/UI/FormRegionPrivacyStatus.cs	Tue Feb 20 17:07:50 2018 +0100
    11.2 +++ b/UI/FormRegionPrivacyStatus.cs	Tue Mar 06 14:40:46 2018 +0100
    11.3 @@ -194,11 +194,104 @@
    11.4              // Build the dialog
    11.5              try
    11.6              {
    11.7 -                PEPMessage message;
    11.8 -                if (PEPMessage.Create((this.OutlookItem as Outlook.MailItem), out message) == Globals.ReturnStatus.Success)
    11.9 +                // The PEPMessage to build the dialog with
   11.10 +                PEPMessage message = null;
   11.11 +
   11.12 +                // If message is a draft, create it directly from the Outlook mail item
   11.13 +                if ((this.OutlookItem as Outlook.MailItem)?.GetIsDraft() == true)
   11.14                  {
   11.15 -                    message.Rating = this.cryptableMailItem.LastProcessedRating;
   11.16 +                    Log.Verbose("BuildAndShowManager: Creating PEPMessage from draft.");
   11.17  
   11.18 +                    if (PEPMessage.Create((this.OutlookItem as Outlook.MailItem), out message) != Globals.ReturnStatus.Success)
   11.19 +                    {
   11.20 +                        Log.Error("BuildAndShowManager: Error creating PEPMessage from draft.");
   11.21 +                        message = null;
   11.22 +                    }
   11.23 +                }
   11.24 +                else
   11.25 +                {
   11.26 +                    // Else, use either the cryptable mail item's associated mirror or message
   11.27 +                    message = this.cryptableMailItem.Mirror ?? this.cryptableMailItem.Message;
   11.28 +                    Log.Verbose(string.Format("BuildAndShowManager: Message {0} retrieved from CryptableMailItem", ((message != null) ? "successfully" : "could not be")));
   11.29 +
   11.30 +                    // As fallback, if we don't have a message yet, create it
   11.31 +                    if (message == null)
   11.32 +                    {
   11.33 +                        Log.Verbose("BuildAndShowManager: Using fallback method to get message.");
   11.34 +
   11.35 +                        Outlook.MailItem omi = null;
   11.36 +                        Outlook.MailItem mirror = null;
   11.37 +
   11.38 +                        try
   11.39 +                        {
   11.40 +                            omi = this.OutlookItem as Outlook.MailItem;
   11.41 +
   11.42 +                            // For securely stored mails, try to look up mirror
   11.43 +                            if (omi?.GetIsSecurelyStored() == true)
   11.44 +                            {
   11.45 +                                mirror = omi?.GetMirror();
   11.46 +
   11.47 +                                if (mirror != null)
   11.48 +                                {
   11.49 +                                    // If mirror is found, use it to create PEPMessage
   11.50 +                                    omi = mirror;
   11.51 +                                    Log.Verbose("BuildAndShowManager: Mirror found.");
   11.52 +                                }
   11.53 +                                else
   11.54 +                                {
   11.55 +                                    // If no mirror is found, decrypt message and use decrypted one (do not 
   11.56 +                                    // decrypt forcefully protected messages).
   11.57 +                                    if (PEPMessage.Create(omi, out message) == Globals.ReturnStatus.Success)
   11.58 +                                    {
   11.59 +                                        var msgProcessor = new MsgProcessor();
   11.60 +                                        PEPMessage decryptedMsg = null;
   11.61 +                                        if (string.IsNullOrEmpty(message.ForceProtectionId) &&
   11.62 +                                            msgProcessor.Decrypt(message, out decryptedMsg))
   11.63 +                                        {
   11.64 +                                            message = decryptedMsg;
   11.65 +                                        }
   11.66 +                                        else
   11.67 +                                        {
   11.68 +                                            message = null;
   11.69 +                                            Log.Error("BuildAndShowManager: Error decrypting message.");
   11.70 +                                        }
   11.71 +                                    }
   11.72 +                                    else
   11.73 +                                    {
   11.74 +                                        message = null;
   11.75 +                                        Log.Error("BuildAndShowManager: Error creating PEPMessage from mirror.");
   11.76 +                                    }
   11.77 +                                }
   11.78 +                            }
   11.79 +
   11.80 +                            // If we don't have a PEPMessage yet, create it
   11.81 +                            if (message == null)
   11.82 +                            {
   11.83 +                                Log.Verbose("BuildAndShowManager: Creating PEPMessage.");
   11.84 +
   11.85 +                                if (PEPMessage.Create(omi, out message) != Globals.ReturnStatus.Success)
   11.86 +                                {
   11.87 +                                    message = null;
   11.88 +                                    Log.Error("BuildAndShowManager: Error creating PEPMessage.");
   11.89 +                                }
   11.90 +                            }
   11.91 +                        }
   11.92 +                        catch (Exception ex)
   11.93 +                        {
   11.94 +                            Log.Error("FormRegionPrivacyStatus.Message: Error converting message. " + ex.ToString());
   11.95 +                        }
   11.96 +                        finally
   11.97 +                        {
   11.98 +                            omi = null;
   11.99 +                            mirror = null;
  11.100 +                        }
  11.101 +                    }
  11.102 +                }
  11.103 +
  11.104 +                // Build dialog
  11.105 +                if (message != null)
  11.106 +                {
  11.107 +                    message.Rating = AdapterExtensions.ReevaluateMessageRating(message);
  11.108                      handshakeDialog = new HandshakeDialog(message, this.cryptableMailItem.Myself);
  11.109                      handshakeDialog.OnUpdateStatus += HandshakeDialog_Updated;
  11.110                      handshakeDialog.Closed += HandshakeDialog_Closed;
  11.111 @@ -206,12 +299,7 @@
  11.112                  }
  11.113                  else
  11.114                  {
  11.115 -                    // If an error occurs, show warning dialog
  11.116 -                    MessageBox.Show(Properties.Resources.PrivacyStatus_RatingUndefinedExplanation,
  11.117 -                                    Properties.Resources.Handshake_StandardFormText,
  11.118 -                                                         MessageBoxButtons.OK,
  11.119 -                                                         MessageBoxIcon.Warning);
  11.120 -                    Log.Error("BuildAndShowManager: Error creating PEPMessage.");
  11.121 +                    throw new Exception("Could not build handshake dialog. Message is null.");
  11.122                  }
  11.123              }
  11.124              catch (Exception ex)
  11.125 @@ -784,8 +872,7 @@
  11.126                  if (this.isEnabled)
  11.127                  {
  11.128                      // If forcefully protected, run dedicated decryption
  11.129 -                    if (omi.GetIsForceFullyProtected() &&
  11.130 -                        omi.GetIsIncoming())
  11.131 +                    if (omi.GetIsForcefullyProtected())
  11.132                      {
  11.133                          var fppMessage = new FPPMessage(omi);
  11.134                          if (fppMessage.GetMessageType() != null)
  11.135 @@ -1059,12 +1146,7 @@
  11.136                                   */
  11.137                                  try
  11.138                                  {
  11.139 -                                    if (this.cryptableMailItem.Mirror != null)
  11.140 -                                    {
  11.141 -                                        this.MailItem_GetMirrorCompleted(null, new CryptableMailItem.GetMirrorCompletedEventArgs(this.cryptableMailItem.Mirror));
  11.142 -                                        Log.Verbose("MailItem_ProcessingComplete: Displaying mirror.");
  11.143 -                                    }
  11.144 -                                    else if (this.cryptableMailItem.IsSecurelyStored || this.cryptableMailItem.IsSecureAttachedMail)
  11.145 +                                    if (this.cryptableMailItem.IsSecurelyStored || this.cryptableMailItem.IsSecureAttachedMail)
  11.146                                      {
  11.147                                          Log.Verbose("MailItem_ProcessingComplete: Starting mirror location.");
  11.148                                          this.cryptableMailItem.StartGetMirror(this.cryptableMailItem.MessageId);
  11.149 @@ -1111,7 +1193,7 @@
  11.150  
  11.151                              // If the message was forcefully protected, there is no mirror and we show the actual message
  11.152                              if ((e.Mirror == null) &&
  11.153 -                                (this.OutlookItem as Outlook.MailItem).GetIsForceFullyProtected())
  11.154 +                                (this.OutlookItem as Outlook.MailItem).GetIsForcefullyProtected())
  11.155                              {
  11.156                                  PEPMessage mirror = null;
  11.157                                  if (PEPMessage.Create((this.OutlookItem as Outlook.MailItem), out mirror) == Globals.ReturnStatus.Success)
    12.1 --- a/UI/HandshakeDialog.xaml.cs	Tue Feb 20 17:07:50 2018 +0100
    12.2 +++ b/UI/HandshakeDialog.xaml.cs	Tue Mar 06 14:40:46 2018 +0100
    12.3 @@ -111,11 +111,13 @@
    12.4                                 PEPIdentity myself)
    12.5          {
    12.6              // If message or myself are null, we can't create the dialog.
    12.7 -            if (message == null ||
    12.8 -                myself == null)
    12.9 +            if (message == null)
   12.10              {
   12.11 -                Log.Error("HandshakeDialog: Message or Myself identity are null.");
   12.12 -                return;
   12.13 +                throw new Exception("Message is null.");
   12.14 +            }
   12.15 +            if (myself == null)
   12.16 +            {
   12.17 +                throw new Exception("Myself is null.");
   12.18              }
   12.19  
   12.20              this.InitializeDialog();
   12.21 @@ -720,10 +722,7 @@
   12.22                              }
   12.23  
   12.24                              // Check if PGP user and show fingerprint tab in this case
   12.25 -                            if ((identity.CommunicationType == pEpComType.pEpCtOpenPGPUnconfirmed) ||
   12.26 -                                (identity.CommunicationType == pEpComType.pEpCtOpenPGP) ||
   12.27 -                                (identity.CommunicationType == pEpComType.pEpCtOpenPGPWeak) ||
   12.28 -                                (identity.CommunicationType == pEpComType.pEpCtOpenPGPWeakUnconfirmed))
   12.29 +                            if (ThisAddIn.PEPEngine.IsPepUser(identity.ToCOMType()) == false)
   12.30                              {
   12.31                                  item.AreTabControlsVisible = true;
   12.32                                  item.ActiveTab = HandshakeItem.Tabs.Fingerprint;
   12.33 @@ -763,14 +762,16 @@
   12.34                                              // Hide if expander is collapsed
   12.35                                              item.ItemImage = imageNoColor;
   12.36                                              item.IsButtonVisible = false;
   12.37 +                                            item.IsClickable = false;
   12.38                                              break;
   12.39                                          }
   12.40                                      case pEpColor.pEpColorRed:
   12.41                                      default:
   12.42                                          {
   12.43                                              // Red identities can not be interacted with
   12.44 +                                            item.ItemImage = imageNoColor;
   12.45                                              item.IsButtonVisible = false;
   12.46 -                                            item.ItemImage = imageNoColor;
   12.47 +                                            item.IsClickable = false;
   12.48                                              break;
   12.49                                          }
   12.50                                  }
    13.1 --- a/pEpForOutlook.csproj	Tue Feb 20 17:07:50 2018 +0100
    13.2 +++ b/pEpForOutlook.csproj	Tue Mar 06 14:40:46 2018 +0100
    13.3 @@ -41,7 +41,7 @@
    13.4      <PublishUrl>publish\</PublishUrl>
    13.5      <InstallUrl>https://pep-project.org/</InstallUrl>
    13.6      <TargetCulture>en</TargetCulture>
    13.7 -    <ApplicationVersion>1.1.30.0</ApplicationVersion>
    13.8 +    <ApplicationVersion>1.0.90.0</ApplicationVersion>
    13.9      <AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
   13.10      <UpdateEnabled>true</UpdateEnabled>
   13.11      <UpdateInterval>0</UpdateInterval>
   13.12 @@ -213,6 +213,9 @@
   13.13      <Reference Include="Microsoft.Office.Interop.Outlook, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
   13.14        <EmbedInteropTypes>True</EmbedInteropTypes>
   13.15      </Reference>
   13.16 +    <Reference Include="Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
   13.17 +      <EmbedInteropTypes>True</EmbedInteropTypes>
   13.18 +    </Reference>
   13.19      <Reference Include="Microsoft.Office.Tools, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
   13.20        <EmbedInteropTypes>False</EmbedInteropTypes>
   13.21      </Reference>