Merge with OUT-431
authorThomas
Thu, 17 May 2018 15:41:18 +0200
changeset 22015c9f9d4ec13f
parent 2199 5c8c43f38243
parent 2200 c578f001cfe5
child 2202 27584ccea6f4
Merge with OUT-431
     1.1 --- a/CryptableMailItem.cs	Thu May 17 11:21:56 2018 +0200
     1.2 +++ b/CryptableMailItem.cs	Thu May 17 15:41:18 2018 +0200
     1.3 @@ -1455,8 +1455,11 @@
     1.4                          KeySyncWizard.Wizard?.AddToReceivedSyncMessages(message);
     1.5                      }
     1.6  
     1.7 +                    // Define decryption flags
     1.8 +                    decryptionFlags = IsSecurelyStored ? pEpDecryptFlags.pEpDecryptFlagUntrustedServer : pEpDecryptFlags.pEpDecryptFlagsNone;
     1.9 +
    1.10                      // Process
    1.11 -                    status = msgProcessor.ProcessMessage(message,
    1.12 +                    status = msgProcessor.ProcessMessage(ref message,
    1.13                                                           sts1,
    1.14                                                           this.internalMailItem.GetIsInSecureStore(),
    1.15                                                           this.internalMailItem.GetIsInSentFolder(),
    1.16 @@ -1464,7 +1467,7 @@
    1.17                                                           out mirror,
    1.18                                                           out processedMessage,
    1.19                                                           out processedRating,
    1.20 -                                                         out decryptionFlags);
    1.21 +                                                         ref decryptionFlags);
    1.22  
    1.23                      if (status == Globals.ReturnStatus.Success)
    1.24                      {
    1.25 @@ -1518,6 +1521,22 @@
    1.26  
    1.27                                      mailItem = mirrorMailItem;
    1.28  
    1.29 +                                    /* If we have extra keys and are on an untrusted server, reencrypt message
    1.30 +                                     * for myself and the extra keys.
    1.31 +                                     */ 
    1.32 +                                    bool saveInternalMailItem = false;
    1.33 +                                    if (decryptionFlags.HasFlag(pEpDecryptFlags.pEpDecryptFlagSrcModified))
    1.34 +                                    {
    1.35 +                                        if (message.ApplyTo(this.internalMailItem, false, false, true, false) == Globals.ReturnStatus.Success)
    1.36 +                                        {
    1.37 +                                            saveInternalMailItem = true;
    1.38 +                                        }
    1.39 +                                        else
    1.40 +                                        {
    1.41 +                                            Log.Error("ProcessAndGetRating: Error reencrypting with extra keys.");
    1.42 +                                        }
    1.43 +                                    }
    1.44 +
    1.45                                      /* OUT - 283 Remove attachment icon for messages on untrusted servers 
    1.46                                       * in case decrypted mail has no attachments.
    1.47                                       * This is needed for all Exchange stores and IMAP stores on Outlook 2010.
    1.48 @@ -1545,7 +1564,7 @@
    1.49                                                  attachment = null;
    1.50                                              }
    1.51  
    1.52 -                                            this.internalMailItem.Save();
    1.53 +                                            saveInternalMailItem = true;
    1.54                                          }
    1.55                                          catch (Exception ex)
    1.56                                          {
    1.57 @@ -1557,6 +1576,19 @@
    1.58                                              attachment = null;
    1.59                                          }
    1.60                                      }
    1.61 +
    1.62 +                                    // Save mail item again if needed
    1.63 +                                    if (saveInternalMailItem)
    1.64 +                                    {
    1.65 +                                        try
    1.66 +                                        {
    1.67 +                                            this.internalMailItem.Save();
    1.68 +                                        }
    1.69 +                                        catch (Exception ex)
    1.70 +                                        {
    1.71 +                                            Log.Error("ProcessAndGetRating: Error saving internal mail item. " + ex.ToString());
    1.72 +                                        }
    1.73 +                                    }
    1.74                                  }
    1.75                                  else
    1.76                                  {
     2.1 --- a/FPPMessage.cs	Thu May 17 11:21:56 2018 +0200
     2.2 +++ b/FPPMessage.cs	Thu May 17 15:41:18 2018 +0200
     2.3 @@ -178,11 +178,12 @@
     2.4                  PEPMessage processedMessage;
     2.5                  pEpRating processedRating;
     2.6                  string[] keyList;
     2.7 -                pEpDecryptFlags flags;
     2.8 +                pEpDecryptFlags flags = pEpDecryptFlags.pEpDecryptFlagsNone;
     2.9  
    2.10                  // Decrypt incoming message
    2.11                  MsgProcessor msgProcessor = new MsgProcessor();
    2.12 -                if (msgProcessor.Decrypt(this.CurrentMessage, out processedMessage, out keyList, out flags, out processedRating) == false)
    2.13 +                PEPMessage message = this.CurrentMessage;
    2.14 +                if (msgProcessor.Decrypt(ref message, out processedMessage, out keyList, ref flags, out processedRating) == false)
    2.15                  {
    2.16                      Log.Error("FPPMessage.ProcessIncoming: Error decrypting incoming message.");
    2.17                      return Globals.ReturnStatus.Failure;
     3.1 --- a/MsgProcessor.cs	Thu May 17 11:21:56 2018 +0200
     3.2 +++ b/MsgProcessor.cs	Thu May 17 15:41:18 2018 +0200
     3.3 @@ -11,7 +11,7 @@
     3.4      /// <summary>
     3.5      /// Class containing processing methods for PEPMessages.
     3.6      /// </summary>
     3.7 -    internal class MsgProcessor : IDisposable
     3.8 +    internal class MsgProcessor
     3.9      {
    3.10          /// <summary>
    3.11          /// Event handler for when a sync message is being detected during decryption.
    3.12 @@ -19,16 +19,6 @@
    3.13          public delegate void SyncMessageReceivedHandler(object sender, MsgProcessor.SyncMessageEventArgs e);
    3.14          public static event SyncMessageReceivedHandler SyncMessageReceived;
    3.15  
    3.16 -        public delegate void ProcessingCompletedHandler(object sender, ProcessingCompletedEventArgs e);
    3.17 -
    3.18 -        /// <summary>
    3.19 -        /// Event when processing is completed.
    3.20 -        /// WARNING: The calling thread is a background worker.
    3.21 -        /// </summary>
    3.22 -        public event ProcessingCompletedHandler ProcessingCompleted;
    3.23 -
    3.24 -        private BackgroundWorker backgroundProcessor;
    3.25 -
    3.26          /**************************************************************
    3.27           * 
    3.28           * Constructors/Destructors
    3.29 @@ -40,77 +30,6 @@
    3.30          /// </summary>
    3.31          public MsgProcessor()
    3.32          {
    3.33 -            // Setup the message processor background worker
    3.34 -            backgroundProcessor = new BackgroundWorker();
    3.35 -            backgroundProcessor.WorkerSupportsCancellation = false;
    3.36 -            backgroundProcessor.RunWorkerCompleted += BackgroundProcessor_RunWorkerCompleted;
    3.37 -            backgroundProcessor.DoWork += BackgroundProcessor_DoWork;
    3.38 -        }
    3.39 -
    3.40 -        /// <summary>
    3.41 -        /// Implementing IDisposable
    3.42 -        /// </summary>
    3.43 -        public void Dispose()
    3.44 -        {
    3.45 -            backgroundProcessor.Dispose();
    3.46 -        }
    3.47 -
    3.48 -        /**************************************************************
    3.49 -         * 
    3.50 -         * Event Handling
    3.51 -         * 
    3.52 -         *************************************************************/
    3.53 -
    3.54 -        // not const because a TimeSpan cannot be const, but meant to be read only.
    3.55 -        private static TimeSpan SECOND = new TimeSpan(0, 0, 1);
    3.56 -
    3.57 -        /// <summary>
    3.58 -        /// Event handler for when the processor background worker is doing work.
    3.59 -        /// </summary>
    3.60 -        private void BackgroundProcessor_DoWork(object sender, DoWorkEventArgs e)
    3.61 -        {
    3.62 -            PEPMessage processedMessage;
    3.63 -            PEPMessage mirror;
    3.64 -            pEpRating processedRating;
    3.65 -            pEpDecryptFlags decryptionFlags;
    3.66 -            MsgContainer msgCont;
    3.67 -            Globals.ReturnStatus sts;
    3.68 -            ProcessingCompletedEventArgs args = null;
    3.69 -
    3.70 -            if (e.Argument is MsgContainer)
    3.71 -            {
    3.72 -                msgCont = e.Argument as MsgContainer;
    3.73 -
    3.74 -                sts = this.ProcessMessage(msgCont.Message,
    3.75 -                                          msgCont.MessageCreationStatus,
    3.76 -                                          msgCont.IsInSecureStore,
    3.77 -                                          msgCont.IsInSentFolder,
    3.78 -                                          msgCont.IsDraft,
    3.79 -                                          out mirror,
    3.80 -                                          out processedMessage,
    3.81 -                                          out processedRating,
    3.82 -                                          out decryptionFlags);
    3.83 -
    3.84 -                args = new ProcessingCompletedEventArgs();
    3.85 -                args.IsMirror = (mirror != null);
    3.86 -                args.ProcessedDecryptionFlags = decryptionFlags;
    3.87 -                args.ProcessedMessage = processedMessage;
    3.88 -                args.ProcessedRating = processedRating;
    3.89 -                args.ProcessedStatus = sts;
    3.90 -            }
    3.91 -
    3.92 -            e.Result = args;
    3.93 -            return;
    3.94 -        }
    3.95 -
    3.96 -        /// <summary>
    3.97 -        /// Event handler for when the processor background worker is completed.
    3.98 -        /// </summary>
    3.99 -        private void BackgroundProcessor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   3.100 -        {
   3.101 -            Log.Verbose("MsgProcessor.BackgroundProcessor: Completed");
   3.102 -            this.ProcessingCompleted?.Invoke(this, (e.Result as ProcessingCompletedEventArgs));
   3.103 -            return;
   3.104          }
   3.105  
   3.106          /**************************************************************
   3.107 @@ -207,24 +126,6 @@
   3.108          }
   3.109  
   3.110          /// <summary>
   3.111 -        /// Starts the processing of the mail item which can result in decryption or encryption of the message.
   3.112 -        /// This will also return the latest message rating.
   3.113 -        /// </summary>
   3.114 -        /// <param name="msgCont">The message container to process with.</param>
   3.115 -        /// <returns>True if the processing started successfully, otherwise false if it is already busy.</returns>
   3.116 -        public bool StartProcessing(MsgContainer msgCont)
   3.117 -        {
   3.118 -            if (this.backgroundProcessor.IsBusy == false)
   3.119 -            {
   3.120 -                Log.Verbose("MsgProcessor.BackgroundProcessor: Started");
   3.121 -                this.backgroundProcessor.RunWorkerAsync(msgCont);
   3.122 -                return (true);
   3.123 -            }
   3.124 -
   3.125 -            return (false);
   3.126 -        }
   3.127 -
   3.128 -        /// <summary>
   3.129          /// Processes the given message including any decryption where necessary.
   3.130          /// This will then return the latest pEp rating for the message.
   3.131          /// If rating is ever undefined: it can be assumed an error occured.
   3.132 @@ -255,7 +156,8 @@
   3.133          ///         |     |      |-- Sent folder        => No decryption needed 
   3.134          ///         |     |      |-- Not in Sent folder => Decrypt for message flags
   3.135          /// 
   3.136 -        /// <param name="message">The original message to process.</param>
   3.137 +        /// <param name="message">The original message to process. Can be returned modified (reencrypted). This will be
   3.138 +        /// signalled by the pEpDecryptFlagSrcModified flag.</param>
   3.139          /// <param name="messageCreationStatus">The return status after creating the message.</param>
   3.140          /// <param name="mirror">The existing mirror for the original message (if any).</param>
   3.141          /// <param name="isInSecureStore">Whether the message being processed is in a secure (untrusted) store.</param>
   3.142 @@ -266,9 +168,9 @@
   3.143          /// <param name="outProcessedMessage">The processed message. This will contain any updated data for either 
   3.144          /// the original message or the mirror. Use the 'outIsMirror' pararameter to determine which.</param>
   3.145          /// <param name="outProcessedRating">The processed rating of the message.</param>
   3.146 -        /// <param name="outDecryptionFlags">The output flags after decrypting the message (if it was decrypted).</param>
   3.147 +        /// <param name="decryptionFlags">The output flags after decrypting the message (if it was decrypted).</param>
   3.148          /// <returns>The status of the method.</returns>
   3.149 -        public Globals.ReturnStatus ProcessMessage(PEPMessage message,
   3.150 +        public Globals.ReturnStatus ProcessMessage(ref PEPMessage message,
   3.151                                                     Globals.ReturnStatus messageCreationStatus,
   3.152                                                     bool isInSecureStore,
   3.153                                                     bool isInSentFolder,
   3.154 @@ -276,12 +178,11 @@
   3.155                                                     out PEPMessage outMirror,
   3.156                                                     out PEPMessage outProcessedMessage,
   3.157                                                     out pEpRating outProcessedRating,
   3.158 -                                                   out pEpDecryptFlags outDecryptionFlags)
   3.159 +                                                   ref pEpDecryptFlags decryptionFlags)
   3.160          {
   3.161              bool success = true;
   3.162              bool sentItem = false;
   3.163              string[] decryptionKeyList;
   3.164 -            pEpDecryptFlags decryptionFlags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.165              PEPMessage processedMessage = null;
   3.166              PEPMessage mirror = null;
   3.167              pEpRating processedRating = pEpRating.pEpRatingUndefined;
   3.168 @@ -315,10 +216,10 @@
   3.169                                  Log.Verbose("ProcessMessage: Secure message");
   3.170  
   3.171                                  // Decrypt message
   3.172 -                                success = this.Decrypt(message,
   3.173 +                                success = this.Decrypt(ref message,
   3.174                                                         out processedMessage,
   3.175                                                         out decryptionKeyList,
   3.176 -                                                       out decryptionFlags,
   3.177 +                                                       ref decryptionFlags,
   3.178                                                         out decryptionRating);
   3.179  
   3.180                                  if (success == false)
   3.181 @@ -353,10 +254,10 @@
   3.182                                  Log.Verbose("ProcessMessage: In secure store or never unprotected");
   3.183  
   3.184                                  // Decrypt message
   3.185 -                                success = this.Decrypt(message,
   3.186 +                                success = this.Decrypt(ref message,
   3.187                                                         out processedMessage,
   3.188                                                         out decryptionKeyList,
   3.189 -                                                       out decryptionFlags,
   3.190 +                                                       ref decryptionFlags,
   3.191                                                         out decryptionRating);
   3.192  
   3.193                                  if (success)
   3.194 @@ -378,10 +279,10 @@
   3.195                                  Log.Verbose("ProcessMessage: Unsecure (trusted) store");
   3.196  
   3.197                                  // Decrypt message
   3.198 -                                success = this.Decrypt(message,
   3.199 +                                success = this.Decrypt(ref message,
   3.200                                                         out processedMessage,
   3.201                                                         out decryptionKeyList,
   3.202 -                                                       out decryptionFlags,
   3.203 +                                                       ref decryptionFlags,
   3.204                                                         out decryptionRating);
   3.205  
   3.206                                  if (success)
   3.207 @@ -419,10 +320,10 @@
   3.208                                   * The processed message itself can be ignored.
   3.209                                  */
   3.210                                  PEPMessage outMessage;
   3.211 -                                this.Decrypt(message,
   3.212 +                                this.Decrypt(ref message,
   3.213                                               out outMessage,
   3.214                                               out decryptionKeyList,
   3.215 -                                             out decryptionFlags);
   3.216 +                                             ref decryptionFlags);
   3.217                              }
   3.218  
   3.219                              /* Check all unsecure messages that are not sent to myself
   3.220 @@ -491,7 +392,6 @@
   3.221              outMirror = mirror;
   3.222              outProcessedMessage = processedMessage;
   3.223              outProcessedRating = processedRating;
   3.224 -            outDecryptionFlags = decryptionFlags;
   3.225  
   3.226              return status;
   3.227          }
   3.228 @@ -975,10 +875,10 @@
   3.229                              out PEPMessage decryptedMessage)
   3.230          {
   3.231              string[] keyList;
   3.232 -            pEpDecryptFlags flags;
   3.233 +            pEpDecryptFlags flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.234              pEpRating rating;
   3.235  
   3.236 -            return this.Decrypt(sourceMessage, out decryptedMessage, out keyList, out flags, out rating);
   3.237 +            return this.Decrypt(ref sourceMessage, out decryptedMessage, out keyList, ref flags, out rating);
   3.238          }
   3.239  
   3.240          /// <summary>
   3.241 @@ -991,13 +891,13 @@
   3.242          /// <param name="flags">Decryption flags by the engine.</param>
   3.243          /// <param name="rating">The output pEp rating after decryption.</param>
   3.244          /// <returns>True if decryption was considered successful, otherwise false.</returns>
   3.245 -        public bool Decrypt(PEPMessage sourceMessage,
   3.246 +        public bool Decrypt(ref PEPMessage sourceMessage,
   3.247                              out PEPMessage destMessage,
   3.248                              out string[] keyList,
   3.249 -                            out pEpDecryptFlags flags,
   3.250 +                            ref pEpDecryptFlags flags,
   3.251                              out pEpRating rating)
   3.252          {
   3.253 -            rating = this.Decrypt(sourceMessage, out destMessage, out keyList, out flags);
   3.254 +            rating = this.Decrypt(ref sourceMessage, out destMessage, out keyList, ref flags);
   3.255  
   3.256              if ((rating == pEpRating.pEpRatingB0rken) ||
   3.257                  (rating == pEpRating.pEpRatingUndefined) ||
   3.258 @@ -1020,18 +920,17 @@
   3.259          /// <param name="keyList">The output keylist used to decrypt.</param>
   3.260          /// <param name="flags">Decryption flags by the engine.</param>
   3.261          /// <returns>The pEp rating after decryption.</returns>
   3.262 -        public pEpRating Decrypt(PEPMessage sourceMessage,
   3.263 +        public pEpRating Decrypt(ref PEPMessage sourceMessage,
   3.264                                   out PEPMessage destMessage,
   3.265                                   out string[] keyList,
   3.266 -                                 out pEpDecryptFlags flags)
   3.267 +                                 ref pEpDecryptFlags flags)
   3.268          {
   3.269              bool success = false;
   3.270 -            TextMessage src;
   3.271 +            TextMessage src = new TextMessage();
   3.272              TextMessage dst = new TextMessage();
   3.273              string[] dstKeyList = Globals.ThisAddIn.Settings.ExtraKeys ?? new string[0];
   3.274              pEpRating rating = pEpRating.pEpRatingCannotDecrypt;
   3.275              Globals.ReturnStatus sts;
   3.276 -            flags = pEpDecryptFlags.pEpDecryptFlagsNone;
   3.277  
   3.278              Log.Verbose("Decrypt started.");
   3.279              Log.SensitiveData("Decrypt: Decrypting " + sourceMessage?.Id);
   3.280 @@ -1042,7 +941,7 @@
   3.281                  try
   3.282                  {
   3.283                      src = sourceMessage.ToCOMType();
   3.284 -                    rating = ThisAddIn.PEPEngine.DecryptMessage(src, out dst, ref dstKeyList, ref flags);
   3.285 +                    rating = ThisAddIn.PEPEngine.DecryptMessage(ref src, out dst, ref dstKeyList, ref flags);
   3.286                      success = true;
   3.287                  }
   3.288                  catch (COMException ex)
   3.289 @@ -1067,6 +966,15 @@
   3.290                  // Copy over lost properties
   3.291                  destMessage.SetNonEnginePropertiesFrom(sourceMessage);
   3.292                  keyList = dstKeyList;
   3.293 +
   3.294 +                // Replace original if needed
   3.295 +                if (flags.HasFlag(pEpDecryptFlags.pEpDecryptFlagSrcModified))
   3.296 +                {
   3.297 +                    PEPMessage reencryptedMessage;
   3.298 +                    sts = PEPMessage.Create(src, out reencryptedMessage);
   3.299 +                    reencryptedMessage.SetNonEnginePropertiesFrom(sourceMessage);
   3.300 +                    sourceMessage = reencryptedMessage;
   3.301 +                }
   3.302              }
   3.303              else
   3.304              {
     4.1 --- a/PEPMessage.cs	Thu May 17 11:21:56 2018 +0200
     4.2 +++ b/PEPMessage.cs	Thu May 17 15:41:18 2018 +0200
     4.3 @@ -1525,14 +1525,19 @@
     4.4          /// Important: Setting this to true for outgoing messages can cause problems with Exchange accounts.</param>
     4.5          /// <param name="setRecipients">Whether to set the message recipients manually. This should normally be set to true
     4.6          /// for all common messages and makes only sense to be omitted in special cases like a FPP reply message.</param>
     4.7 +        /// <param name="convertToPGPMIMEAttachment">Whether to convert the message into a PGP/MIME attachment if needed.
     4.8 +        /// The default behaviour is to convert if the message is PGP/MIME encrypted, which is needed for all outgoing messages
     4.9 +        /// in order for Outlook to send the message correctly. For special cases like when using EncryptForSelf, we might not 
    4.10 +        /// want ot do that, so the parameter can be set to false.</param>
    4.11          /// <returns>The status of the method.</returns>
    4.12          public Globals.ReturnStatus ApplyTo(Outlook.MailItem omi,
    4.13                                              bool setInternalHeaderFields,
    4.14                                              bool setSender,
    4.15 -                                            bool setRecipients = true)
    4.16 +                                            bool setRecipients = true,
    4.17 +                                            bool? convertToPGPMIMEAttachment = null)
    4.18          {
    4.19              bool fromRecipientRemoved = false;
    4.20 -            bool isPGPMIMEMsg = this.IsPGPMIMEEncrypted;
    4.21 +            bool isPGPMIMEMsg = convertToPGPMIMEAttachment ?? this.IsPGPMIMEEncrypted;
    4.22              byte[] bytes;
    4.23              Outlook.Attachments attachments = null;
    4.24              Outlook.Recipient newRecipient = null;