Merge with default sync
authorThomas
Tue, 05 Mar 2019 14:45:53 +0100
branchsync
changeset 2594 b4351ec5c330
parent 2577 f5b55f5a3184 (current diff)
parent 2593 c266c7e55440 (diff)
child 2610 09fde2338362
Merge with default
PEPIdentity.cs
ThisAddIn.cs
--- a/Extensions/MailItemExtensions.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/Extensions/MailItemExtensions.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -52,7 +52,8 @@
         {
             Undefined,
             ProcessInBackground,
-            Processed
+            Processed,
+            ProcessedAvoidWinmailDat
         }
 
         // Default values for pEp properties.
@@ -340,6 +341,8 @@
             omi?.DeleteUserProperty(CryptableMailItem.USER_PROPERTY_KEY_ENABLE_PROTECTION);
             omi?.DeleteUserProperty(CryptableMailItem.USER_PROPERTY_KEY_IS_ORIGINALLY_ENCRYPTED);
             omi?.DeleteUserProperty(CryptableMailItem.USER_PROPERTY_KEY_ORIGINAL_RATING);
+            omi?.DeleteUserProperty(MailItemExtensions.USER_PROPERTY_KEY_ORIG_ENTRY_ID);
+            omi?.DeleteUserProperty(MailItemExtensions.USER_PROPERTY_KEY_PROCESSING_STATE);
 
             // Do not allow TNEF/RTF format with 'winmail.dat' attachment
             MapiHelper.SetProperty(omi, MapiProperty.PidLidUseTnef, false);
@@ -2036,10 +2039,13 @@
                     // Avoid creation of 'winmail.dat' attachment if needed
                     if (processedMessage.IsSecure == false)
                     {
-                        omi.AvoidWinmailDatAttachment();
+                        omi.SetProcessingState(MailItemExtensions.ProcessingState.ProcessedAvoidWinmailDat);
                     }
-
-                    omi.SetProcessingState(MailItemExtensions.ProcessingState.Processed);
+                    else
+                    {
+                        omi.SetProcessingState(MailItemExtensions.ProcessingState.Processed);
+                    }
+
                     omi.Send();
                 }
                 catch (Exception ex)
--- a/PEPIdentity.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/PEPIdentity.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -950,7 +950,7 @@
                 catch (Exception ex)
                 {
                     identity = null;
-                    Log.Error("GetOwnIdentity: Error determining getting own identity. " + ex.ToString());
+                    Log.Error("GetOwnIdentity: Error determining own identity. " + ex.ToString());
                 }
             }
             else
@@ -1999,7 +1999,7 @@
             // A resolved recipient has an address entry. This should be the common case. If an address entry can be retrieved,
             // run through the full Create() method. If no address entry is available, create a new pEp identity from the recipient.
             if ((addressEntry != null) &&
-                (Create(addressEntry, out newIdent, addContact) == Globals.ReturnStatus.Success))
+                (PEPIdentity.Create(addressEntry, out newIdent, addContact) == Globals.ReturnStatus.Success))
             {
                 status = Globals.ReturnStatus.Success;
             }
@@ -2086,8 +2086,6 @@
             Outlook.ExchangeDistributionList exchDL = null;
             Outlook.AddressEntries exchDLMembers = null;
             Outlook.ExchangeUser exchUser = null;
-            Globals.ReturnStatus sts;
-            Globals.ReturnStatus status = Globals.ReturnStatus.Success;
 
             ///////////////////////////////////////////////////////////
             // Pre-process
@@ -2164,8 +2162,14 @@
 
                             if (currentMember != null)
                             {
-                                sts = PEPIdentity.Create(currentMember, out PEPIdentity member, addContact);
-                                newIdent.Members.Add(member);
+                                if (PEPIdentity.Create(currentMember, out PEPIdentity member, addContact) == Globals.ReturnStatus.Success)
+                                {
+                                    newIdent.Members.Add(member);
+                                }
+                                else
+                                {
+                                    Log.Error("PEPIdentity.Create: Error creating member from contact list.");
+                                }
 
                                 currentMember = null;
                             }
@@ -2429,7 +2433,7 @@
             contact = null;
 
             identity = newIdent;
-            return (status);
+            return (identityCreated ? Globals.ReturnStatus.Success : Globals.ReturnStatus.Failure);
         }
 
         /// <summary>
--- a/PEPMessage.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/PEPMessage.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -49,6 +49,8 @@
         public const string PEP_HIDDEN_SYNC_MESSAGE_BODY                 = "This message is part of p≡p's concept to synchronize. \n\nYou can safely ignore it. It will be deleted automatically.";
         public const string PEP_HIDDEN_SYNC_MESSAGE_SUBJECT              = "p≡p synchronization message - please ignore";
 
+        public const string PEPTUNNEL_MAIL_ADDRESS         = "@peptunnel.com";
+
         private static readonly object                      mutexMirror           = new object();
         private static readonly Dictionary<string, string>  mirrorCache           = new Dictionary<string, string>();
 
@@ -76,6 +78,7 @@
         private string              _PEPProtocolVersion;
         private pEpRating           _Rating;
         private DateTime?           _ReceivedOn;
+        private List<PEPIdentity>   _ReplyTo;
         private DateTime?           _SentOn;
         private string              _ShortMsg;
         private List<PEPIdentity>   _To;
@@ -465,67 +468,6 @@
         }
 
         /// <summary>
-        /// Gets the outgoing rating of this message.
-        /// <param name="ignoreOptions">Ignore user settings like ForceProtection or
-        /// ForceUnencrypted and return always calculated engine rating.</param>
-        /// </summary>
-        public pEpRating GetOutgoingRating(bool ignoreOptions = false,
-                                           bool previewOnly = false)
-        {
-            pEpRating rating = pEpRating.pEpRatingUndefined;
-
-#if READER_RELEASE_MODE
-            // If reader mode, always unencrypted
-            rating = pEpRating.pEpRatingUnencrypted;
-#else
-            // If message has BCC recipients, always return unencrypted
-            if (this.Bcc?.Count > 0)
-            {
-                return pEpRating.pEpRatingUnencrypted;
-            }
-
-            if (ignoreOptions == false)
-            {
-                /* If message is forcefully unencrypted, return Unencrypted.
-                 * If message is forcefully encrypted, return Reliable.
-                 */
-                if (this.ForceUnencrypted)
-                {
-                    return pEpRating.pEpRatingUnencrypted;
-                }
-                else if (string.IsNullOrEmpty(this.ForceProtectionId) == false)
-                {
-                    return pEpRating.pEpRatingReliable;
-                }
-            }
-
-            // If we have no rating at this point, calculate it
-            PEPMessage workingMessage = this.Copy(true);
-            workingMessage.FlattenAllRecipientIdentities();
-            workingMessage.Direction = pEpMsgDirection.pEpDirOutgoing;
-
-            try
-            {
-                if (previewOnly)
-                {
-                    rating = ThisAddIn.PEPEngine.OutgoingMessageRatingPreview(workingMessage.ToCOMType());
-                }
-                else
-                {
-                    rating = ThisAddIn.PEPEngine.OutgoingMessageRating(workingMessage.ToCOMType());
-                }
-            }
-            catch (Exception ex)
-            {
-                rating = pEpRating.pEpRatingUndefined;
-                Log.Error("GetOutgoingRating: Error getting outgoing rating from engine. " + ex.ToString());
-            }
-
-#endif
-            return rating;
-        }
-
-        /// <summary>
         /// Gets or sets the pEp protocol (or 'format') version of this message.
         /// This is not to be confused with pEp engine version which can be different.
         /// This is commonly set after decryption.
@@ -581,6 +523,16 @@
         }
 
         /// <summary>
+        /// Gets the list of identities in the Reply-To field.
+        ///          MailItem : Corresponds to property 'ReplyRecipients' 
+        ///       TextMessage : Corresponds to property 'ReplyTo'
+        /// </summary>
+        public List<PEPIdentity> ReplyTo
+        {
+            get { return (this._ReplyTo); }
+        }
+
+        /// <summary>
         /// Gets or sets the date and time when the message was sent.
         ///          MailItem : Corresponds to property 'SentOn'
         /// CryptableMailItem : not supported
@@ -678,8 +630,68 @@
         /// <param name="propertyName">The name of the property that changed.</param>
         private void RaisePropertyChangedEvent(string propertyName)
         {
-            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-            return;
+            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));           
+        }
+
+        /// <summary>
+        /// Gets the outgoing rating of this message.
+        /// <param name="ignoreOptions">Ignore user settings like ForceProtection or
+        /// ForceUnencrypted and return always calculated engine rating.</param>
+        /// </summary>
+        public pEpRating GetOutgoingRating(bool ignoreOptions = false,
+                                           bool previewOnly = false)
+        {
+            pEpRating rating = pEpRating.pEpRatingUndefined;
+
+#if READER_RELEASE_MODE
+            // If reader mode, always unencrypted
+            rating = pEpRating.pEpRatingUnencrypted;
+#else
+            // If message has BCC recipients, always return unencrypted
+            if (this.Bcc?.Count > 0)
+            {
+                return pEpRating.pEpRatingUnencrypted;
+            }
+
+            if (ignoreOptions == false)
+            {
+                /* If message is forcefully unencrypted, return Unencrypted.
+                 * If message is forcefully encrypted, return Reliable.
+                 */
+                if (this.ForceUnencrypted)
+                {
+                    return pEpRating.pEpRatingUnencrypted;
+                }
+                else if (string.IsNullOrEmpty(this.ForceProtectionId) == false)
+                {
+                    return pEpRating.pEpRatingReliable;
+                }
+            }
+
+            // If we have no rating at this point, calculate it
+            PEPMessage workingMessage = this.Copy(true);
+            workingMessage.FlattenAllRecipientIdentities();
+            workingMessage.Direction = pEpMsgDirection.pEpDirOutgoing;
+
+            try
+            {
+                if (previewOnly)
+                {
+                    rating = ThisAddIn.PEPEngine.OutgoingMessageRatingPreview(workingMessage.ToCOMType());
+                }
+                else
+                {
+                    rating = ThisAddIn.PEPEngine.OutgoingMessageRating(workingMessage.ToCOMType());
+                }
+            }
+            catch (Exception ex)
+            {
+                rating = pEpRating.pEpRatingUndefined;
+                Log.Error("GetOutgoingRating: Error getting outgoing rating from engine. " + ex.ToString());
+            }
+
+#endif
+            return rating;
         }
 
         /// <summary>
@@ -700,6 +712,7 @@
             List<pEpIdentity> bcc = new List<pEpIdentity>();
             List<pEpIdentity> cc = new List<pEpIdentity>();
             List<pEpIdentity> to = new List<pEpIdentity>();
+            List<pEpIdentity> replyTo = new List<pEpIdentity>();
             List<StringPair> optionalFields = new List<StringPair>();
             StringPair field;
             TextMessage result = new TextMessage();
@@ -830,6 +843,12 @@
                 recvSec = (long)span.TotalSeconds;
             }
 
+            // Convert ReplyTo
+            for (int i = 0; i < this._ReplyTo.Count; i++)
+            {
+                replyTo.Add(this.ReplyTo[i].ToCOMType());
+            }
+
             // SentOn
             sentSec = -1;
             if (this._SentOn != null)
@@ -877,6 +896,7 @@
             result.LongMsgFormatted = this._LongMsgFormattedHtml;
             result.OptFields = optionalFields.ToArray();
             result.Recv = ((recvSec >= 0) ? recvSec : result.Recv);
+            result.ReplyTo = replyTo.ToArray();
             result.Sent = ((sentSec >= 0) ? sentSec : result.Sent);
             result.ShortMsg = this._ShortMsg;
             result.To = to.ToArray();
@@ -1002,6 +1022,24 @@
                 message.MessageId = pEpMessage.Id;
             }
 
+            // ReplyTo
+            for (int i = 0; i < pEpMessage.ReplyTo?.Count; i++)
+            {
+                try
+                {
+                    if (InternetAddress.TryParse(pEpMessage.ReplyTo[i].Address, out InternetAddress address))
+                    {
+                        address.Name = pEpMessage.ReplyTo[i].UserName;
+                        message.ReplyTo.Add(address);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    status = Globals.ReturnStatus.Failure;
+                    Log.Error("ToMIMEMessage: Error parsing ReplyTo identity. " + ex.ToString());
+                }
+            }
+
             // Subject
             if (string.IsNullOrEmpty(pEpMessage.ShortMsg) == false)
             {
@@ -1197,6 +1235,7 @@
                 Comparisons.Equals(this.PEPProtocolVersion, obj.PEPProtocolVersion) &&
                 Comparisons.Equals(this.Rating, obj.Rating) &&
                 Comparisons.Equals(this.ReceivedOn, obj.ReceivedOn) &&
+                Comparisons.Equals(this.ReplyTo, obj.ReplyTo) &&
                 Comparisons.Equals(this.SentOn, obj.SentOn) &&
                 Comparisons.Equals(this.ShortMsg, obj.ShortMsg) &&
                 Comparisons.Equals(this.To, obj.To))
@@ -1333,6 +1372,13 @@
                 copy.ReceivedOn = null;
             }
 
+            // ReplyTo
+            copy.ReplyTo.Clear();
+            for (int i = 0; i < this._ReplyTo.Count; i++)
+            {
+                copy.ReplyTo.Add(this._ReplyTo[i].Copy());
+            }
+
             // SentOn
             if (this._SentOn != null)
             {
@@ -1384,6 +1430,7 @@
             this._PEPProtocolVersion = null;
             this._Rating = pEpRating.pEpRatingUndefined;
             this._ReceivedOn = null;
+            this._ReplyTo = new List<PEPIdentity>();
             this._SentOn = null;
             this._ShortMsg = null;
             this._To = new List<PEPIdentity>();
@@ -1411,6 +1458,7 @@
             this.RaisePropertyChangedEvent(nameof(this.PEPProtocolVersion));
             this.RaisePropertyChangedEvent(nameof(this.Rating));
             this.RaisePropertyChangedEvent(nameof(this.ReceivedOn));
+            this.RaisePropertyChangedEvent(nameof(this.ReplyTo));
             this.RaisePropertyChangedEvent(nameof(this.SentOn));
             this.RaisePropertyChangedEvent(nameof(this.ShortMsg));
             this.RaisePropertyChangedEvent(nameof(this.To));
@@ -1640,7 +1688,7 @@
                             // Marshal.ReleaseComObject(newRecipient);
                             newRecipient = null;
                         }
-                    }
+                    }                    
                 }
 
                 /* Add the pEp From identity as its own recipient. This will be removed later.
@@ -1801,6 +1849,29 @@
                         recipients.ResolveAll();
                     }
                     catch { }
+                }                
+
+                // ReplyTo recipients
+                recipients = omi.ReplyRecipients;
+                while (recipients?.Count > 0)
+                {
+                    recipients.Remove(1);
+                }
+
+                for (int i = 0; i < this._ReplyTo.Count; i++)
+                {
+                    if (string.IsNullOrWhiteSpace(this._ReplyTo[i].Address) == false)
+                    {
+                        // Add by address
+                        newRecipient = recipients.Add(this._ReplyTo[i].Address);
+                        newRecipient = null;
+                    }
+                    else if (string.IsNullOrWhiteSpace(this._ReplyTo[i].UserName) == false)
+                    {
+                        // Add by user name (required for distribution lists)
+                        newRecipient = recipients.Add(this._ReplyTo[i].UserName);
+                        newRecipient = null;
+                    }
                 }
 
                 // Gather properties to set via MAPI
@@ -1948,7 +2019,6 @@
                 {
                     // Note: ignore return status
                     propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.KeyList), this._KeyList);
-                    propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.KeyImport), this._KeyImport);
 
                     // Only store rating once and never change it
                     if (omi.GetPEPProperty(MailItemExtensions.PEPProperty.Rating, out object storedRating) &&
@@ -1961,6 +2031,7 @@
                 // Note: ignore return status
                 propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.AutoConsume), this._AutoConsume);
                 propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.ForceProtectionId), this._ForceProtectionId);
+                propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.KeyImport), this._KeyImport);
                 propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.NeverUnsecure), this._NeverUnsecure);
                 propertiesToSet.AddPEPMessageProperty(nameof(PEPMessage.PEPProtocolVersion), this._PEPProtocolVersion);
 
@@ -2375,6 +2446,16 @@
                     newMessage.ReceivedOn = null;
                 }
 
+                // ReplyTo
+                newMessage.ReplyTo.Clear();
+                if (msg.ReplyTo != null)
+                {
+                    for (int i = 0; i < msg.ReplyTo.Length; i++)
+                    {
+                        newMessage.ReplyTo.Add(new PEPIdentity((pEpIdentity)msg.ReplyTo.GetValue(i)));
+                    }
+                }
+
                 // SentOn
                 if (msg.Sent > 0)
                 {
@@ -2528,6 +2609,28 @@
 
                     recipient = null;
                 }
+
+                recipients = omi.ReplyRecipients;
+                for (int i = 1; i <= recipients.Count; i++)
+                {
+                    recipient = recipients[i];
+                    sts = PEPIdentity.Create(recipient, out PEPIdentity ident);
+                    if (sts == Globals.ReturnStatus.Success)
+                    {
+                        newMessage.ReplyTo.Add(ident);
+                    }
+                    else
+                    {
+                        // Update the status, only the first failure type is recorded
+                        if (status == Globals.ReturnStatus.Success)
+                        {
+                            status = sts;
+                        }
+
+                        Log.Error("PEPMessage.Create: Failure creating 'ReplyTo' identity.");
+                    }
+                }
+
                 Log.Verbose("PEPMessage.Create: Recipients calculated, calculating main properties.");
 
                 if (onlyRecipientsAndDirection == false)
@@ -2743,6 +2846,22 @@
                     else
                     {
                         newMessage.KeyImport = transportHeaders?.FirstOrDefault(a => (a.Field == PEPMessage.PR_PEP_KEY_IMPORT_NAME || a.Field == PEPMessage.PR_PEP_KEY_IMPORT_NAME_OLD))?.Value?.Trim();
+
+                        // Check backup solution with ReplyTo tunnel if needed
+                        if (string.IsNullOrEmpty(newMessage.KeyImport) &&
+                            (newMessage.ReplyTo?.Count > 0))
+                        {
+                            for (int i = 0; i < newMessage.ReplyTo.Count; i++)
+                            {
+                                string address = newMessage.ReplyTo[i].Address?.Trim();
+                                if (address?.EndsWith(PEPMessage.PEPTUNNEL_MAIL_ADDRESS) == true)
+                                {
+                                    string keyImportFpr = address.Split('@')?.GetValue(0) as string;
+                                    newMessage.KeyImport = keyImportFpr.ToUpperInvariant();
+                                    break;
+                                }
+                            }
+                        }
                     }
 
                     // Key list
--- a/Properties/AssemblyInfo.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/Properties/AssemblyInfo.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -46,5 +46,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.208.0")]
-[assembly: AssemblyFileVersion("1.0.208.0")]
+[assembly: AssemblyVersion("1.0.209.0")]
+[assembly: AssemblyFileVersion("1.0.209.0")]
--- a/ThisAddIn.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/ThisAddIn.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -790,12 +790,10 @@
         /// <param name="validateSendingAccount">Validates that the SendingAccount matches the From identity of the given message.
         /// This can catch situations (and throw exceptions) where the default account would be used instead.</param>
         /// <param name="processMessage">Whether or not to process this message through the pEp engine.</param>
-        /// <param name="setKeyImportHeader">Whether or not to process this message through the pEp engine.</param>
         internal void CreateAndSendMessage(PEPMessage message,
                                            bool deleteAfterSend,
                                            bool validateSendingAccount,
-                                           bool processMessage = false,
-                                           bool setKeyImportHeader = false)
+                                           bool processMessage = false)
         {
             Outlook.MailItem newItem;
             Globals.ReturnStatus sts;
@@ -827,32 +825,11 @@
                     // Do not allow TNEF/RTF format with 'winmail.dat' attachment
                     MapiHelper.SetProperty(newItem, MapiProperty.PidLidUseTnef, false);
 
-                    // If ForceUnencrypted property is set, add it to mail item
-                    bool save = false;
-                    if (message.ForceUnencrypted)
+                    // If ForceUnencrypted property is set, add it to mail item (only if message is to be processed)
+                    if (processMessage && 
+                        message.ForceUnencrypted)
                     {
                         newItem.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, true);
-                        save = true;
-                    }
-
-                    // Set KeyImport header if necessary
-                    if (setKeyImportHeader)
-                    {
-                        newItem.SetPEPProperty(MailItemExtensions.PEPProperty.KeyImport, message.KeyImport);
-                        save = true;
-                    }
-
-                    // Save if necessary
-                    if (save)
-                    {
-                        try
-                        {
-                            newItem.Save();
-                        }
-                        catch (Exception ex)
-                        {
-                            Log.Error("CreateAndSendMessage: Error saving new item. " + ex.ToString());
-                        }
                     }
 
                     /* Send
@@ -3339,6 +3316,12 @@
                         Log.Verbose("Application_ItemSend: Message already processed. Sending directly...");
                         return;
                     }
+                    else if (processingState == MailItemExtensions.ProcessingState.ProcessedAvoidWinmailDat)
+                    {
+                        Log.Verbose("Application_ItemSend: Message already processed. Preventing Winmail.dat and sending directly...");
+                        omi.AvoidWinmailDatAttachment();
+                        return;
+                    }
 
                     // Check for special cases
                     bool processMessage = true;
--- a/UI/KeySyncWizard.xaml.cs	Fri Feb 22 17:01:56 2019 +0100
+++ b/UI/KeySyncWizard.xaml.cs	Tue Mar 05 14:45:53 2019 +0100
@@ -1559,7 +1559,6 @@
                         }
 
                         // Create basic message
-                        bool processMessage = true;
                         PEPMessage message = new PEPMessage
                         {
                             From = this.Myself,
@@ -1572,6 +1571,10 @@
                         };
                         message.To.Add(this.Partner);
 
+                        // Tunnel the fingerprint also through the Reply-To field in the following format: <fingerprint>@peptunnel.com
+                        string keyImportAddress = string.Concat(message.KeyImport, PEPMessage.PEPTUNNEL_MAIL_ADDRESS);
+                        message.ReplyTo.Add(new PEPIdentity(keyImportAddress));
+
                         Log.Verbose("SendSyncMessage: Basic message successfully created.");
 
                         // If message type isn't InitialMessage, encrypt it accordingly
@@ -1581,7 +1584,16 @@
                         {
                             case MessageTypes.InitialMessage:
                                 {
-                                    Log.Verbose("SendSyncMessage: Initial message. Won't encrypt.");
+                                    if (msgProcessor.Encrypt(message, out msg, null, pEpEncryptFlags.pEpEncryptFlagDefault, pEpEncFormat.pEpEncNone))
+                                    {
+                                        Log.Verbose("SendSyncMessage: Initial message successfully created.");
+                                        message = msg;
+                                    }
+                                    else
+                                    {
+                                        Log.Error("SendSyncMessage: Error creating initial message.");
+                                        message = null;
+                                    }
                                 }
                                 break;
                             case MessageTypes.PublicKeyMessage:
@@ -1591,7 +1603,6 @@
                                     {
                                         Log.Verbose("SendSyncMessage: Public key message successfully created.");
                                         message = msg;
-                                        processMessage = false;
                                     }
                                     else
                                     {
@@ -1607,7 +1618,6 @@
                                     {
                                         Log.Verbose("SendSyncMessage: Private key message successfully created.");
                                         message = msg;
-                                        processMessage = false;
                                     }
                                     else
                                     {
@@ -1646,8 +1656,8 @@
                                 }
                             }
 
-                            // Send message
-                            Globals.ThisAddIn.CreateAndSendMessage(message, true, true, processMessage, true);
+                            // Send message (do not process as it's already processed at this point)
+                            Globals.ThisAddIn.CreateAndSendMessage(message, true, true, false);
 
                             // Log that message has been sent
                             this.sentMessages?.Add(messageType);
--- a/pEpForOutlook.csproj	Fri Feb 22 17:01:56 2019 +0100
+++ b/pEpForOutlook.csproj	Tue Mar 05 14:45:53 2019 +0100
@@ -44,7 +44,7 @@
     <PublishUrl>publish\</PublishUrl>
     <InstallUrl>https://pep-project.org/</InstallUrl>
     <TargetCulture>en</TargetCulture>
-    <ApplicationVersion>1.0.208.0</ApplicationVersion>
+    <ApplicationVersion>1.0.209.0</ApplicationVersion>
     <AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
     <UpdateEnabled>true</UpdateEnabled>
     <UpdateInterval>0</UpdateInterval>