Merge in OUT-401
authorThomas
Thu, 15 Feb 2018 13:31:50 +0100
changeset 2008fa305b491940
parent 1999 dfab19314f7d
parent 2007 31da7a34305e
child 2009 0ca0c0824911
Merge in OUT-401
     1.1 --- a/CryptableMailItem.cs	Mon Feb 12 16:40:36 2018 +0100
     1.2 +++ b/CryptableMailItem.cs	Thu Feb 15 13:31:50 2018 +0100
     1.3 @@ -1037,26 +1037,10 @@
     1.4                          return (pEpRating.pEpRatingUnencrypted);
     1.5                      }
     1.6  
     1.7 -                    PEPMessage msg;
     1.8 -                    MsgProcessor processor = new MsgProcessor();
     1.9 -                    Globals.ReturnStatus sts;
    1.10 -
    1.11 +                    // Else calculate it
    1.12                      lock (mutexMailItem)
    1.13                      {
    1.14 -                        sts = PEPMessage.Create(this.internalMailItem, out msg, true);
    1.15 -                    }
    1.16 -
    1.17 -                    if (sts == Globals.ReturnStatus.Success)
    1.18 -                    {
    1.19 -                        msg.FlattenAllRecipientIdentities();
    1.20 -                        msg.Direction = pEpMsgDirection.pEpDirOutgoing;
    1.21 -
    1.22 -                        rating = processor.GetOutgoingRating(msg);
    1.23 -                    }
    1.24 -                    else
    1.25 -                    {
    1.26 -                        // Return undefined if a failure occured creating the message
    1.27 -                        rating = pEpRating.pEpRatingUndefined;
    1.28 +                        rating = this.internalMailItem.GetOutgoingRating();
    1.29                      }
    1.30  #endif
    1.31                  }
     2.1 --- a/Extensions/MailItemExtensions.cs	Mon Feb 12 16:40:36 2018 +0100
     2.2 +++ b/Extensions/MailItemExtensions.cs	Thu Feb 15 13:31:50 2018 +0100
     2.3 @@ -2086,7 +2086,7 @@
     2.4              try
     2.5              {
     2.6                  PEPMessage message;
     2.7 -                if (PEPMessage.Create(omi, out message) == Globals.ReturnStatus.Success)
     2.8 +                if (PEPMessage.Create(omi, out message, true, false) == Globals.ReturnStatus.Success)
     2.9                  {
    2.10                      if (message.ForceUnencrypted)
    2.11                      {
    2.12 @@ -2098,6 +2098,8 @@
    2.13                      }
    2.14                      else
    2.15                      {
    2.16 +                        message.FlattenAllRecipientIdentities();
    2.17 +                        message.Direction = pEpMsgDirection.pEpDirOutgoing;
    2.18                          rating = ThisAddIn.PEPEngine.OutgoingMessageRating(message.ToCOMType());
    2.19                      }
    2.20                  }
     3.1 --- a/PEPIdentity.cs	Mon Feb 12 16:40:36 2018 +0100
     3.2 +++ b/PEPIdentity.cs	Thu Feb 15 13:31:50 2018 +0100
     3.3 @@ -3,8 +3,6 @@
     3.4  using System.Collections.Generic;
     3.5  using System.ComponentModel;
     3.6  using System.Linq;
     3.7 -using System.Runtime.InteropServices;
     3.8 -using System.Text.RegularExpressions;
     3.9  using Outlook = Microsoft.Office.Interop.Outlook;
    3.10  
    3.11  namespace pEp
    3.12 @@ -844,19 +842,19 @@
    3.13          /// <returns>True if the given address represents an own identity, otherwise false.</returns>
    3.14          public static bool GetIsOwnIdentity(string address)
    3.15          {
    3.16 -            bool isMyself;
    3.17 -            Outlook.Account account;
    3.18 +            bool isMyself = false;
    3.19  
    3.20 -            account = PEPIdentity.GetOwnAccount(address);
    3.21 -            isMyself = (account != null ? true : false);
    3.22 -
    3.23 -            if (account != null)
    3.24 +            try
    3.25              {
    3.26 -                // Marshal.ReleaseComObject(account);
    3.27 -                account = null;
    3.28 +                isMyself = Globals.ThisAddIn.Settings.AccountSettingsList.Any(a => (a.SmtpAddress?.Equals(address) == true));
    3.29 +            }
    3.30 +            catch (Exception ex)
    3.31 +            {
    3.32 +                isMyself = false;
    3.33 +                Log.Error("GetIsOwnIdentity: Error determining if own identity. " + ex.ToString());
    3.34              }
    3.35  
    3.36 -            return (isMyself);
    3.37 +            return isMyself;
    3.38          }
    3.39  
    3.40          /// <summary>
    3.41 @@ -1144,7 +1142,7 @@
    3.42                              own = new PEPIdentity();
    3.43                              own.Address = address;
    3.44                              own.UserName = userName;
    3.45 -                            own.UserId = Globals.ThisAddIn.GetUserId(own.Address, null); // Not using 'myself ID'
    3.46 +                            own.UserId = Globals.ThisAddIn.GetUserId(own.Address); // Not using 'myself ID'
    3.47  
    3.48                              // Update the identity in the pEp engine (and get fingerprint)
    3.49                              try
    3.50 @@ -1288,7 +1286,7 @@
    3.51                      }
    3.52  
    3.53                      // Add user ID
    3.54 -                    newIdentity.UserId = Globals.ThisAddIn.GetUserId(newIdentity.Address, null);
    3.55 +                    newIdentity.UserId = Globals.ThisAddIn.GetUserId(newIdentity.Address);
    3.56                  }
    3.57              }
    3.58              catch (Exception ex)
    3.59 @@ -1454,11 +1452,11 @@
    3.60                      {
    3.61                          exchangeUser = true;
    3.62                      }
    3.63 -                    /* SenderEmailType showed to be null in some occasions. Therefore, we need to 
    3.64 -                     * doublecheck if this is an Exchange user.
    3.65 -                     */
    3.66                      else if (omi.SenderEmailType == null)
    3.67                      {
    3.68 +                        /* SenderEmailType showed to be null in some occasions. Therefore, we need to 
    3.69 +                         * doublecheck if this is an Exchange user.
    3.70 +                         */
    3.71                          try
    3.72                          {
    3.73                              // Exchange address types, see: https://msdn.microsoft.com/en-us/library/office/ff868214.aspx
    3.74 @@ -1495,24 +1493,25 @@
    3.75                                      from.Address = exchSender.PrimarySmtpAddress;
    3.76                                      from.UserName = exchSender.Name;
    3.77  
    3.78 -                                    // Add the contact force unencrypted property
    3.79 +                                    // Add the contact if necessary
    3.80                                      try
    3.81                                      {
    3.82 -                                        contact = exchSender.GetContact();
    3.83 +                                        contact = exchSender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName, "EX");
    3.84 +                                        from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
    3.85  
    3.86 -                                        if (contact != null)
    3.87 -                                        {
    3.88 -                                            from.IsForceUnencrypted = contact.GetForceUnencrypted();
    3.89 -                                            // Marshal.ReleaseComObject(contact);
    3.90 -                                            contact = null;
    3.91 -                                        }
    3.92 +                                        // Read the contact's ForceUnencrypted property
    3.93 +                                        from.IsForceUnencrypted = contact?.GetForceUnencrypted();
    3.94 +
    3.95 +                                        status = Globals.ReturnStatus.Success;
    3.96                                      }
    3.97 -                                    catch { }
    3.98 -
    3.99 -                                    // Add the user ID
   3.100 -                                    from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
   3.101 -
   3.102 -                                    status = Globals.ReturnStatus.Success;
   3.103 +                                    catch (Exception ex)
   3.104 +                                    {
   3.105 +                                        Log.Error("GetFromIdentity: Error getting contact. " + ex.ToString());
   3.106 +                                    }
   3.107 +                                    finally
   3.108 +                                    {
   3.109 +                                        contact = null;
   3.110 +                                    }
   3.111                                  }
   3.112                                  else
   3.113                                  {
   3.114 @@ -1526,24 +1525,25 @@
   3.115                                  from.Address = (string)MapiHelper.GetProperty(sender, MapiProperty.PidTagSmtpAddress);
   3.116                                  from.UserName = sender.Name;
   3.117  
   3.118 -                                // Add the contact force unencrypted property
   3.119 +                                // Add the contact if necessary
   3.120                                  try
   3.121                                  {
   3.122 -                                    contact = sender.GetContact();
   3.123 +                                    contact = sender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName, "EX");
   3.124 +                                    from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
   3.125  
   3.126 -                                    if (contact != null)
   3.127 -                                    {
   3.128 -                                        from.IsForceUnencrypted = contact.GetForceUnencrypted();
   3.129 -                                        // Marshal.ReleaseComObject(contact);
   3.130 -                                        contact = null;
   3.131 -                                    }
   3.132 +                                    // Read the contact's ForceUnencrypted property
   3.133 +                                    from.IsForceUnencrypted = contact?.GetForceUnencrypted();
   3.134 +
   3.135 +                                    status = Globals.ReturnStatus.Success;
   3.136                                  }
   3.137 -                                catch { }
   3.138 -
   3.139 -                                // Add the user ID
   3.140 -                                from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
   3.141 -
   3.142 -                                status = Globals.ReturnStatus.Success;
   3.143 +                                catch (Exception ex)
   3.144 +                                {
   3.145 +                                    Log.Error("GetFromIdentity: Error getting contact. " + ex.ToString());
   3.146 +                                }
   3.147 +                                finally
   3.148 +                                {
   3.149 +                                    contact = null;
   3.150 +                                }
   3.151                              }
   3.152                          }
   3.153                          catch
   3.154 @@ -1563,24 +1563,25 @@
   3.155                          from.Address = omi.SenderEmailAddress;
   3.156                          from.UserName = omi.SenderName;
   3.157  
   3.158 -                        // Add the contact force unencrypted property
   3.159 +                        // Add the contact if necessary
   3.160                          try
   3.161                          {
   3.162 -                            contact = sender.GetContact();
   3.163 +                            contact = sender.GetContact() ?? PEPIdentity.CreateContact(from.Address, from.UserName);
   3.164 +                            from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
   3.165  
   3.166 -                            if (contact != null)
   3.167 -                            {
   3.168 -                                from.IsForceUnencrypted = contact.GetForceUnencrypted();
   3.169 -                                // Marshal.ReleaseComObject(contact);
   3.170 -                                contact = null;
   3.171 -                            }
   3.172 +                            // Read the contact's ForceUnencrypted property
   3.173 +                            from.IsForceUnencrypted = contact?.GetForceUnencrypted();
   3.174 +
   3.175 +                            status = Globals.ReturnStatus.Success;
   3.176                          }
   3.177 -                        catch { }
   3.178 -
   3.179 -                        // Add the user ID
   3.180 -                        from.UserId = Globals.ThisAddIn.GetUserId(from.Address, contact);
   3.181 -
   3.182 -                        status = Globals.ReturnStatus.Success;
   3.183 +                        catch (Exception ex)
   3.184 +                        {
   3.185 +                            Log.Error("GetFromIdentity: Error getting contact. " + ex.ToString());
   3.186 +                        }
   3.187 +                        finally
   3.188 +                        {
   3.189 +                            contact = null;
   3.190 +                        }
   3.191                      }
   3.192                  }
   3.193                  else if (omi.GetIsIncoming() == false) // Probably outgoing if sender is null
   3.194 @@ -1603,30 +1604,10 @@
   3.195              }
   3.196              finally
   3.197              {
   3.198 -                // Release objects
   3.199 -                if (contact != null)
   3.200 -                {
   3.201 -                    // Marshal.ReleaseComObject(contact);
   3.202 -                    contact = null;
   3.203 -                }
   3.204 -
   3.205 -                if (sender != null)
   3.206 -                {
   3.207 -                    // Marshal.ReleaseComObject(sender);
   3.208 -                    sender = null;
   3.209 -                }
   3.210 -
   3.211 -                if (exchSender != null)
   3.212 -                {
   3.213 -                    // Marshal.ReleaseComObject(exchSender);
   3.214 -                    exchSender = null;
   3.215 -                }
   3.216 -
   3.217 -                if (sendingAccount != null)
   3.218 -                {
   3.219 -                    // Marshal.ReleaseComObject(sendingAccount);
   3.220 -                    sendingAccount = null;
   3.221 -                }
   3.222 +                contact = null;
   3.223 +                sender = null;
   3.224 +                exchSender = null;
   3.225 +                sendingAccount = null;
   3.226              }
   3.227  
   3.228              fromIdentity = from;
   3.229 @@ -1634,6 +1615,64 @@
   3.230          }
   3.231  
   3.232          /// <summary>
   3.233 +        /// Creates a ContactItem in the Outlook Address Book. Can return null.
   3.234 +        /// </summary>
   3.235 +        /// <param name="address">The address of the contact to create.</param>
   3.236 +        /// <param name="userName">The user name of the contact to create.</param>
   3.237 +        /// <param name="addressType">The address type of the contact to create. Optional.</param>
   3.238 +        /// <returns>The created contact or null if an error occured.</returns>
   3.239 +        private static Outlook.ContactItem CreateContact(string address, string userName, string addressType = null)
   3.240 +        {
   3.241 +            bool contactExists = false;
   3.242 +            Outlook.ContactItem contact = null;
   3.243 +
   3.244 +            // Doublecheck to make sure there is not already a contact for this address
   3.245 +            Outlook.NameSpace ns = null;
   3.246 +            Outlook.Folder folder = null;
   3.247 +            Outlook.Items items = null;
   3.248 +            try
   3.249 +            {
   3.250 +                ns = Globals.ThisAddIn.Application.Session;
   3.251 +                folder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts) as Outlook.Folder;
   3.252 +                items = folder.Items;
   3.253 +                contactExists = (items.Restrict(string.Format("[Email1Address]='{0}' Or [Email2Address]='{0}' Or [Email3Address]='{0}'", address)) != null);
   3.254 +            }
   3.255 +            catch (Exception ex)
   3.256 +            {
   3.257 +                contactExists = false;
   3.258 +                Log.Error("CreateContact: Error doublechecking existence of contact with same address. " + ex.ToString());
   3.259 +            }
   3.260 +            finally
   3.261 +            {
   3.262 +                ns = null;
   3.263 +                folder = null;
   3.264 +                items = null;
   3.265 +            }
   3.266 +
   3.267 +            // If contact doesn't exist, create it.
   3.268 +            // Make also sure that it's not an own identity.
   3.269 +            if ((contactExists == false) &&
   3.270 +                (PEPIdentity.GetIsOwnIdentity(address) == false))
   3.271 +            {
   3.272 +                try
   3.273 +                {
   3.274 +                    contact = Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olContactItem);
   3.275 +                    contact.Email1Address = address;
   3.276 +                    contact.FullName = userName;
   3.277 +                    contact.Email1AddressType = addressType;
   3.278 +                    contact.Save();
   3.279 +                }
   3.280 +                catch (Exception ex)
   3.281 +                {
   3.282 +                    contact = null;
   3.283 +                    Log.Error("CreateContact: Error creating contact. " + ex.ToString());
   3.284 +                }
   3.285 +            }
   3.286 +
   3.287 +            return contact;
   3.288 +        }
   3.289 +
   3.290 +        /// <summary>
   3.291          /// Gets the default from/sender identity using the default Outlook user.
   3.292          /// Warning: The result can be null.
   3.293          /// </summary>
   3.294 @@ -1690,9 +1729,10 @@
   3.295          /// <param name="identity">The output pEp identity of the recipient (will never be null).</param>
   3.296          /// <returns>The status of the method.</returns>
   3.297          public static Globals.ReturnStatus Create(Outlook.Recipient recipient,
   3.298 -                                                  out PEPIdentity identity)
   3.299 +                                                  out PEPIdentity identity,
   3.300 +                                                  bool addContact = false)
   3.301          {
   3.302 -            string smtpAddress= null;
   3.303 +            string smtpAddress = null;
   3.304              Outlook.AddressEntry addressEntry = null;
   3.305              PEPIdentity newIdent = null;
   3.306              Globals.ReturnStatus status = Globals.ReturnStatus.Success;
   3.307 @@ -1714,7 +1754,7 @@
   3.308              // run through the full Create() method. If no address entry is available, create a new pEp identity from the recipient.
   3.309              if (addressEntry != null)
   3.310              {
   3.311 -                status = Create(addressEntry, out newIdent);
   3.312 +                status = Create(addressEntry, out newIdent, addContact);
   3.313              }
   3.314              else
   3.315              {
   3.316 @@ -1732,10 +1772,19 @@
   3.317                      UserName = recipient?.Name?.Trim()
   3.318                  };
   3.319  
   3.320 -                // Get the unique user ID if possible (Assume no contact is available)
   3.321 +                // Get the unique user ID if possible
   3.322                  if (string.IsNullOrEmpty(newIdent.Address) == false)
   3.323                  {
   3.324 -                    newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, null);
   3.325 +                    Outlook.ContactItem contact = null;
   3.326 +
   3.327 +                    if (addContact)
   3.328 +                    {
   3.329 +                        contact = PEPIdentity.CreateContact(newIdent.Address, newIdent.UserName);
   3.330 +                    }
   3.331 +
   3.332 +                    newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, contact);
   3.333 +
   3.334 +                    contact = null;
   3.335                  }
   3.336              }
   3.337  
   3.338 @@ -1759,7 +1808,8 @@
   3.339          /// <param name="identity">The output pEp identity of the address entry (will never be null).</param>
   3.340          /// <returns>The status of the method.</returns>
   3.341          public static Globals.ReturnStatus Create(Outlook.AddressEntry addressEntry,
   3.342 -                                                  out PEPIdentity identity)
   3.343 +                                                  out PEPIdentity identity,
   3.344 +                                                  bool addContact = false)
   3.345          {
   3.346              bool identityCreated = false;
   3.347              bool? forceUnencryptedProperty = null;
   3.348 @@ -1810,15 +1860,10 @@
   3.349              {
   3.350                  // Save contact for later user ID calculation
   3.351                  contact = addressEntry.GetContact();
   3.352 -                if (contact != null)
   3.353 -                {
   3.354 -                    forceUnencryptedProperty = contact.GetForceUnencrypted();
   3.355 -                }
   3.356              }
   3.357 -            catch
   3.358 -            {
   3.359 -                forceUnencryptedProperty = null;
   3.360 -            }
   3.361 +            catch { }
   3.362 +
   3.363 +            forceUnencryptedProperty = contact?.GetForceUnencrypted();
   3.364  
   3.365              ///////////////////////////////////////////////////////////
   3.366              // Handle Outlook distribution lists
   3.367 @@ -1858,7 +1903,7 @@
   3.368  
   3.369                              if (currentMember != null)
   3.370                              {
   3.371 -                                sts = PEPIdentity.Create(currentMember, out member);
   3.372 +                                sts = PEPIdentity.Create(currentMember, out member, addContact);
   3.373                                  newIdent.Members.Add(member);
   3.374  
   3.375                                  // Marshal.ReleaseComObject(currentMember);
   3.376 @@ -1950,10 +1995,12 @@
   3.377                                      {
   3.378                                          currContact = exchUser.GetContact();
   3.379  
   3.380 -                                        if (currContact != null)
   3.381 +                                        if (contact == null && addContact)
   3.382                                          {
   3.383 -                                            newIdent2.IsForceUnencrypted = currContact.GetForceUnencrypted();
   3.384 +                                            currContact = PEPIdentity.CreateContact(newIdent2.Address, newIdent2.UserName);
   3.385                                          }
   3.386 +
   3.387 +                                        newIdent2.IsForceUnencrypted = currContact?.GetForceUnencrypted();
   3.388                                      }
   3.389                                      catch
   3.390                                      {
   3.391 @@ -1967,23 +2014,9 @@
   3.392                              catch { }
   3.393                              finally
   3.394                              {
   3.395 -                                if (currAddressEntry != null)
   3.396 -                                {
   3.397 -                                    // Marshal.ReleaseComObject(currAddressEntry);
   3.398 -                                    currAddressEntry = null;
   3.399 -                                }
   3.400 -
   3.401 -                                if (exchUser != null)
   3.402 -                                {
   3.403 -                                    // Marshal.ReleaseComObject(exchUser);
   3.404 -                                    exchUser = null;
   3.405 -                                }
   3.406 -
   3.407 -                                if (currContact != null)
   3.408 -                                {
   3.409 -                                    // Marshal.ReleaseComObject(currContact);
   3.410 -                                    currContact = null;
   3.411 -                                }
   3.412 +                                currAddressEntry = null;
   3.413 +                                exchUser = null;
   3.414 +                                currContact = null;
   3.415                              }
   3.416                          }
   3.417                      }
   3.418 @@ -1993,35 +2026,11 @@
   3.419                  catch { }
   3.420                  finally
   3.421                  {
   3.422 -                    if (exchDL != null)
   3.423 -                    {
   3.424 -                        // Marshal.ReleaseComObject(exchDL);
   3.425 -                        exchDL = null;
   3.426 -                    }
   3.427 -
   3.428 -                    if (exchDLMembers != null)
   3.429 -                    {
   3.430 -                        // Marshal.ReleaseComObject(exchDLMembers);
   3.431 -                        exchDLMembers = null;
   3.432 -                    }
   3.433 -
   3.434 -                    if (currAddressEntry != null)
   3.435 -                    {
   3.436 -                        // Marshal.ReleaseComObject(currAddressEntry);
   3.437 -                        currAddressEntry = null;
   3.438 -                    }
   3.439 -
   3.440 -                    if (exchUser != null)
   3.441 -                    {
   3.442 -                        // Marshal.ReleaseComObject(exchUser);
   3.443 -                        exchUser = null;
   3.444 -                    }
   3.445 -
   3.446 -                    if (currContact != null)
   3.447 -                    {
   3.448 -                        // Marshal.ReleaseComObject(currContact);
   3.449 -                        currContact = null;
   3.450 -                    }
   3.451 +                    currContact = null;
   3.452 +                    exchDL = null;
   3.453 +                    exchDLMembers = null;
   3.454 +                    currAddressEntry = null;
   3.455 +                    exchUser = null;
   3.456                  }
   3.457              }
   3.458  
   3.459 @@ -2081,18 +2090,8 @@
   3.460                  // As a fallback, get information from the associated contact
   3.461                  if (string.IsNullOrWhiteSpace(tempAddress))
   3.462                  {
   3.463 -                    try
   3.464 -                    {
   3.465 -                        tempAddress = contact.Email1Address;
   3.466 -                        tempUserName = contact.Email1DisplayName;
   3.467 -                    }
   3.468 -                    catch { }
   3.469 -                }
   3.470 -
   3.471 -                // Add address if possible
   3.472 -                if (string.IsNullOrWhiteSpace(tempAddress) == false)
   3.473 -                {
   3.474 -                    newIdent.Address = tempAddress.Trim();
   3.475 +                    tempAddress = contact?.Email1Address;
   3.476 +                    tempUserName = contact?.Email1DisplayName;
   3.477                  }
   3.478  
   3.479                  // Add user name if possible
   3.480 @@ -2101,27 +2100,25 @@
   3.481                      newIdent.UserName = tempUserName.Trim();
   3.482                  }
   3.483  
   3.484 -                // Get the unique user ID if possible
   3.485 -                if (string.IsNullOrEmpty(newIdent.Address) == false)
   3.486 +                // Add address if possible
   3.487 +                if (string.IsNullOrWhiteSpace(tempAddress) == false)
   3.488                  {
   3.489 -                    newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, contact);
   3.490 +                    newIdent.Address = tempAddress.Trim();
   3.491 +
   3.492 +                    // Add contact if required
   3.493 +                    if ((contact == null) &&
   3.494 +                        addContact)
   3.495 +                    {
   3.496 +                        contact = PEPIdentity.CreateContact(newIdent.Address, newIdent.UserName);
   3.497 +                    }
   3.498                  }
   3.499  
   3.500 +                newIdent.UserId = Globals.ThisAddIn.GetUserId(newIdent.Address, contact);
   3.501 +
   3.502                  identityCreated = true;
   3.503              }
   3.504  
   3.505 -            // Free resources
   3.506 -            if (addressEntry != null)
   3.507 -            {
   3.508 -                // Marshal.ReleaseComObject(addressEntry);
   3.509 -                addressEntry = null;
   3.510 -            }
   3.511 -
   3.512 -            if (contact != null)
   3.513 -            {
   3.514 -                // Marshal.ReleaseComObject(contact);
   3.515 -                contact = null;
   3.516 -            }
   3.517 +            contact = null;
   3.518  
   3.519              identity = newIdent;
   3.520              return (status);
     4.1 --- a/PEPMessage.cs	Mon Feb 12 16:40:36 2018 +0100
     4.2 +++ b/PEPMessage.cs	Thu Feb 15 13:31:50 2018 +0100
     4.3 @@ -2302,6 +2302,8 @@
     4.4          /// <param name="createdMessage">The output newly created message (will never be null).</param>
     4.5          /// <param name="onlyRecipientsAndDirection">Whether to only set recipients and direction. Only set to
     4.6          /// true in special cases, e.g. if the message is only needed to calculate the outgoing rating.</param>
     4.7 +        /// <param name="createContacts">Whether or not to create contacts from the mail items's recipients during
     4.8 +        /// processing of the message. Only set to false in special cases like for outgoing rating.</param>
     4.9          /// <returns>The status of the method.</returns>
    4.10          /// <remarks>In some contexts which call this message, a partial conversion of the
    4.11          /// <see cref="TextMessage"/> is acceptable, non-critical, and better than failure (e. G. displaying
    4.12 @@ -2311,7 +2313,8 @@
    4.13          /// and check the result if appropriate.</remarks>
    4.14          public static Globals.ReturnStatus Create(Outlook.MailItem omi,
    4.15                                                    out PEPMessage createdMessage,
    4.16 -                                                  bool onlyRecipientsAndDirection = false)
    4.17 +                                                  bool onlyRecipientsAndDirection = false,
    4.18 +                                                  bool createContacts = true)
    4.19          {
    4.20              byte[] rtfBody;
    4.21              string delim;
    4.22 @@ -2329,7 +2332,10 @@
    4.23  
    4.24              try
    4.25              {
    4.26 -                Log.Verbose("PEPMessage.Create: Creating new PEPMessage from OMI started, calculating recipients.");
    4.27 +                Log.Verbose("PEPMessage.Create: Creating new PEPMessage from OMI started.");
    4.28 +
    4.29 +                newMessage.Direction = omi.GetIsIncoming() ? pEpMsgDirection.pEpDirIncoming : pEpMsgDirection.pEpDirOutgoing;
    4.30 +                Log.Verbose("PEPMessage.Create: direction calculated.");
    4.31  
    4.32                  // Calculate recipients
    4.33                  newMessage.Bcc.Clear();
    4.34 @@ -2364,7 +2370,7 @@
    4.35                              }
    4.36                          case Outlook.OlMailRecipientType.olCC:
    4.37                              {
    4.38 -                                sts = PEPIdentity.Create(currRecipient, out ident);
    4.39 +                                sts = PEPIdentity.Create(currRecipient, out ident, (createContacts && (newMessage.Direction == pEpMsgDirection.pEpDirOutgoing)));
    4.40                                  if (sts == Globals.ReturnStatus.Success)
    4.41                                  {
    4.42                                      newMessage.Cc.Add(ident);
    4.43 @@ -2384,7 +2390,7 @@
    4.44                              }
    4.45                          case Outlook.OlMailRecipientType.olTo:
    4.46                              {
    4.47 -                                sts = PEPIdentity.Create(currRecipient, out ident);
    4.48 +                                sts = PEPIdentity.Create(currRecipient, out ident, (createContacts && (newMessage.Direction == pEpMsgDirection.pEpDirOutgoing)));
    4.49                                  if (sts == Globals.ReturnStatus.Success)
    4.50                                  {
    4.51                                      newMessage.To.Add(ident);
    4.52 @@ -2410,9 +2416,6 @@
    4.53  
    4.54                  Log.Verbose("PEPMessage.Create: Recipients calculated, calculating main properties.");
    4.55  
    4.56 -                newMessage.Direction = omi.GetIsIncoming() ? pEpMsgDirection.pEpDirIncoming : pEpMsgDirection.pEpDirOutgoing;
    4.57 -                Log.Verbose("PEPMessage.Create: direction calculated.");
    4.58 -
    4.59                  if (onlyRecipientsAndDirection == false)
    4.60                  {
    4.61                      // From
    4.62 @@ -2433,7 +2436,7 @@
    4.63                      }
    4.64                      Log.Verbose("PEPMessage.Create: From identity calculated.");
    4.65  
    4.66 -                    newMessage.Id = (string)MapiHelper.GetProperty(omi, MapiProperty.PidTagInternetMessageId, "");
    4.67 +                    newMessage.Id = MapiHelper.GetProperty(omi, MapiProperty.PidTagInternetMessageId, "") as string;
    4.68                      newMessage.ShortMsg = omi.Subject;
    4.69  
    4.70                      /* Date & Times
     5.1 --- a/PEPSettings.cs	Mon Feb 12 16:40:36 2018 +0100
     5.2 +++ b/PEPSettings.cs	Thu Feb 15 13:31:50 2018 +0100
     5.3 @@ -30,6 +30,8 @@
     5.4              AllMessages
     5.5          }
     5.6  
     5.7 +        public const string PEP_OWN_USER_ID                                     = "pEp_own_userId";
     5.8 +
     5.9          public const string REG_KEY_SOFTWARE                                    = "Software";
    5.10          public const string REG_KEY_PEP                                         = "pEp";
    5.11          public const string REG_KEY_PEP_FOR_OUTLOOK                             = "Outlook";
    5.12 @@ -46,6 +48,7 @@
    5.13          public const string REG_NAME_ACCOUNT_SETTING_SENT_FOLDER_ENTRYID        = "SentFolderEntryId";
    5.14          public const string REG_NAME_ACCOUNT_SETTING_SMTP_ADDRESS               = "SmtpAddress";
    5.15          public const string REG_NAME_ACCOUNT_SETTING_TYPE                       = "Type";
    5.16 +        public const string REG_NAME_ACCOUNT_SETTING_USER_NAME                  = "UserName";
    5.17          public const string REG_NAME_ACCOUNT_WHITELIST                          = "AccountWhitelist";
    5.18          public const string REG_NAME_CRASH_REPORT_SEND_ADDRESS                  = "CrashReportSendAddress";
    5.19          public const string REG_NAME_DEFAULT_CODEPAGE_OUT                       = "Default_CodePageOut"; // Name defined by Microsoft
    5.20 @@ -77,6 +80,7 @@
    5.21          public const string                ACCOUNT_SETTING_SENT_FOLDER_ENTRYID_DEFAULT        = null;
    5.22          public const string                ACCOUNT_SETTING_SMTP_ADDRESS_DEFAULT               = null;
    5.23          public const string                ACCOUNT_SETTING_TYPE_DEFAULT                       = null;
    5.24 +        public const string                ACCOUNT_SETTING_USER_NAME_DEFAULT                  = null;  
    5.25          public static readonly string[]    ACCOUNT_WHITELIST_DEFAULT                          = new string[] { };
    5.26          public static Disclaimer           ADD_DISCLAIMER_DEFAULT                             = Disclaimer.None;
    5.27          public const string                CRASH_REPORT_SEND_ADDRESS_DEFAULT                  = "crashreport@prettyeasyprivacy.com";
    5.28 @@ -782,6 +786,11 @@
    5.29                                              {
    5.30                                                  keyAcctSettings.SetValue(PEPSettings.REG_NAME_ACCOUNT_SETTING_TYPE, acctSettings.Type, RegistryValueKind.String);
    5.31                                              }
    5.32 +
    5.33 +                                            if (acctSettings.UserName != null)
    5.34 +                                            {
    5.35 +                                                keyAcctSettings.SetValue(PEPSettings.REG_NAME_ACCOUNT_SETTING_USER_NAME, acctSettings.UserName, RegistryValueKind.String);
    5.36 +                                            }
    5.37                                          }
    5.38                                      }
    5.39                                  }
    5.40 @@ -1051,6 +1060,17 @@
    5.41                                                          isPropertySet = true;
    5.42                                                      }
    5.43                                                  }
    5.44 +
    5.45 +                                                // UserName
    5.46 +                                                value = keyAcctSettings.GetValue(PEPSettings.REG_NAME_ACCOUNT_SETTING_USER_NAME, null);
    5.47 +                                                if (value != null)
    5.48 +                                                {
    5.49 +                                                    if (string.IsNullOrWhiteSpace((string)value) == false)
    5.50 +                                                    {
    5.51 +                                                        acctSettings.UserName = ((string)value).Trim();
    5.52 +                                                        isPropertySet = true;
    5.53 +                                                    }
    5.54 +                                                }
    5.55                                              }
    5.56                                          }
    5.57                                          catch { }
    5.58 @@ -1806,6 +1826,7 @@
    5.59              protected string        _SentFolderEntryId;
    5.60              protected string        _SmtpAddress;
    5.61              protected string        _Type;
    5.62 +            protected string        _UserName;
    5.63  
    5.64              /**************************************************************
    5.65               * 
    5.66 @@ -1993,6 +2014,22 @@
    5.67                  }
    5.68              }
    5.69  
    5.70 +            /// <summary>
    5.71 +            /// Gets or sets the UserName of the account.
    5.72 +            /// </summary>
    5.73 +            public string UserName
    5.74 +            {
    5.75 +                get { return (this._UserName); }
    5.76 +                set
    5.77 +                {
    5.78 +                    if (object.Equals(this._UserName, value) == false)
    5.79 +                    {
    5.80 +                        this._UserName = value;
    5.81 +                        this.RaisePropertyChangedEvent(nameof(this.UserName));
    5.82 +                    }
    5.83 +                }
    5.84 +            }
    5.85 +
    5.86              /**************************************************************
    5.87               * 
    5.88               * Methods
    5.89 @@ -2023,6 +2060,7 @@
    5.90                  this._SentFolderEntryId = PEPSettings.ACCOUNT_SETTING_SENT_FOLDER_ENTRYID_DEFAULT;
    5.91                  this._SmtpAddress = PEPSettings.ACCOUNT_SETTING_SMTP_ADDRESS_DEFAULT;
    5.92                  this._Type = PEPSettings.ACCOUNT_SETTING_TYPE_DEFAULT;
    5.93 +                this._UserName = PEPSettings.ACCOUNT_SETTING_USER_NAME_DEFAULT;
    5.94  
    5.95                  this.RaisePropertyChangedEvent(nameof(this.AddDisclaimer));
    5.96                  this.RaisePropertyChangedEvent(nameof(this.DisclaimerText));
    5.97 @@ -2033,6 +2071,7 @@
    5.98                  this.RaisePropertyChangedEvent(nameof(this.SentFolderEntryId));
    5.99                  this.RaisePropertyChangedEvent(nameof(this.SmtpAddress));
   5.100                  this.RaisePropertyChangedEvent(nameof(this.Type));
   5.101 +                this.RaisePropertyChangedEvent(nameof(this.UserName));
   5.102              }
   5.103  
   5.104              /// <summary>
   5.105 @@ -2052,6 +2091,7 @@
   5.106                  copy.SentFolderEntryId = this._SentFolderEntryId;
   5.107                  copy.SmtpAddress = this._SmtpAddress;
   5.108                  copy.Type = this._Type;
   5.109 +                copy.UserName = this._UserName;
   5.110  
   5.111                  return (copy);
   5.112              }
     6.1 --- a/ThisAddIn.cs	Mon Feb 12 16:40:36 2018 +0100
     6.2 +++ b/ThisAddIn.cs	Thu Feb 15 13:31:50 2018 +0100
     6.3 @@ -141,7 +141,7 @@
     6.4                          // several times, we need to prevent infinite recursion in case of engine
     6.5                          // initializaition failure.
     6.6                          if (_PEPEngineException != null)
     6.7 -                           return null;
     6.8 +                            return null;
     6.9                          _PEPEngineException = ex;
    6.10  
    6.11                          string summaryMessage = Properties.Resources.Message_InitError + " " +
    6.12 @@ -245,6 +245,7 @@
    6.13                                  acctSettings = new PEPSettings.PEPAccountSettings();
    6.14                                  acctSettings.SmtpAddress = account.SmtpAddress;
    6.15                                  acctSettings.Type = account.AccountType.ToString();
    6.16 +                                acctSettings.UserName = account.UserName;
    6.17  
    6.18                                  // Qualify server trust if not ActiveSync (always trusted as mails don't get synced back to server)
    6.19                                  if (account.AccountType != Outlook.OlAccountType.olEas)
    6.20 @@ -530,61 +531,40 @@
    6.21          /// </summary>
    6.22          internal void RegisterMyself()
    6.23          {
    6.24 -            Outlook.NameSpace ns = null;
    6.25 -            Outlook.Account account = null;
    6.26 -            Outlook.Accounts accounts = null;
    6.27 -            Outlook.Recipient currUser = null;
    6.28              pEpIdentity ownIdentity;
    6.29  
    6.30 -            try
    6.31 +            if (Globals.ThisAddIn.Settings.AccountSettingsList != null)
    6.32              {
    6.33 -                ns = this.Application.Session;
    6.34 -                accounts = ns.Accounts;
    6.35 -
    6.36 -                for (int i = 1; i <= accounts.Count; i++)
    6.37 +                foreach (var acctSetting in Globals.ThisAddIn.Settings.AccountSettingsList)
    6.38                  {
    6.39 -                    account = accounts[i];
    6.40 -                    currUser = account.CurrentUser;
    6.41 -
    6.42 -                    ownIdentity = new pEpIdentity();
    6.43 -                    ownIdentity.Address = account.SmtpAddress;
    6.44 -                    ownIdentity.UserName = (currUser != null ? currUser.Name : null);
    6.45 -                    ownIdentity.UserId = Globals.ThisAddIn.GetUserId(ownIdentity.Address, null);
    6.46 -
    6.47 -                    /* Disable key sync if it is an imap account or sync is disabled globally
    6.48 -                     * AND per account. For new accounts, the sync setting per account gets set
    6.49 -                     * to "false" during SyncAccountsList().
    6.50 -                     */
    6.51 -                    try
    6.52 +                    // Create pEpIdentity
    6.53 +                    ownIdentity = new pEpIdentity
    6.54                      {
    6.55 -                        foreach (var acctSettings in this._Settings.AccountSettingsList)
    6.56 -                        {
    6.57 -                            if (acctSettings.EqualsByAddress(ownIdentity.Address))
    6.58 -                            {
    6.59 -                                if ((acctSettings.Type.Contains("Imap")) ||
    6.60 -                                    ((this._Settings.IsSyncEnabledForAllAccounts == false) &&
    6.61 -                                    (acctSettings.IsSyncEnabled == false)))
    6.62 -                                {
    6.63 -                                    ownIdentity.Flags = pEpIdentityFlags.pEpIdfNotForSync;
    6.64 -                                }
    6.65 -                                break;
    6.66 -                            }
    6.67 -                        }
    6.68 -                    }
    6.69 -                    catch (Exception ex)
    6.70 +                        Address = acctSetting.SmtpAddress,
    6.71 +                        UserId = PEPSettings.PEP_OWN_USER_ID,
    6.72 +                        UserName = acctSetting.UserName
    6.73 +                    };
    6.74 +
    6.75 +                    // Add to userId cache
    6.76 +                    this.userIdCache[ownIdentity.Address] = ownIdentity.UserId;
    6.77 +
    6.78 +                    // Set not for sync flag if necessary
    6.79 +                    if ((acctSetting.Type.Contains("Imap")) ||
    6.80 +                        ((Globals.ThisAddIn.Settings.IsSyncEnabledForAllAccounts == false) &&
    6.81 +                         (acctSetting.IsSyncEnabled == false)))
    6.82                      {
    6.83 -                        Log.Verbose("RegisterMyself: Error setting sync flag for new account. " + ex.ToString());
    6.84 +                        ownIdentity.Flags = pEpIdentityFlags.pEpIdfNotForSync;
    6.85                      }
    6.86  
    6.87                      // Log information if invalid
    6.88                      if (string.IsNullOrWhiteSpace(ownIdentity.Address))
    6.89                      {
    6.90 -                        Log.Warning("RegisterMyself: Myself[" + i.ToString() + "] doesn't have an address.");
    6.91 +                        Log.Warning("RegisterMyself: Myself doesn't have an address.");
    6.92                      }
    6.93  
    6.94                      if (string.IsNullOrWhiteSpace(ownIdentity.UserName))
    6.95                      {
    6.96 -                        Log.Warning("RegisterMyself: Myself[" + i.ToString() + "] doesn't have a user name.");
    6.97 +                        Log.Warning("RegisterMyself: Myself doesn't have a user name.");
    6.98                      }
    6.99  
   6.100                      /* Call engine to register myself (doesn't matter if already done in a past instance)
   6.101 @@ -603,54 +583,8 @@
   6.102                      {
   6.103                          Log.Warning("RegisterMyself: Engine returned exception, " + ex.ToString());
   6.104                      }
   6.105 -
   6.106 -                    // Release objects
   6.107 -                    if (account != null)
   6.108 -                    {
   6.109 -                        // Marshal.ReleaseComObject(account);
   6.110 -                        account = null;
   6.111 -                    }
   6.112 -
   6.113 -                    if (currUser != null)
   6.114 -                    {
   6.115 -                        // Marshal.ReleaseComObject(currUser);
   6.116 -                        currUser = null;
   6.117 -                    }
   6.118                  }
   6.119              }
   6.120 -            catch (Exception ex)
   6.121 -            {
   6.122 -                Log.Error("RegisterMyself: Failure occured, " + ex.ToString());
   6.123 -            }
   6.124 -            finally
   6.125 -            {
   6.126 -                // Release objects
   6.127 -                if (ns != null)
   6.128 -                {
   6.129 -                    //Marshal.ReleaseComObject(ns);
   6.130 -                    ns = null;
   6.131 -                }
   6.132 -
   6.133 -                if (account != null)
   6.134 -                {
   6.135 -                    //Marshal.ReleaseComObject(account);
   6.136 -                    account = null;
   6.137 -                }
   6.138 -
   6.139 -                if (accounts != null)
   6.140 -                {
   6.141 -                    //Marshal.ReleaseComObject(accounts);
   6.142 -                    accounts = null;
   6.143 -                }
   6.144 -
   6.145 -                if (currUser != null)
   6.146 -                {
   6.147 -                    //Marshal.ReleaseComObject(currUser);
   6.148 -                    currUser = null;
   6.149 -                }
   6.150 -            }
   6.151 -
   6.152 -            return;
   6.153          }
   6.154  
   6.155          /// <summary>
   6.156 @@ -661,7 +595,7 @@
   6.157          /// This value can be null and is not required for 'myself' user IDs.</param>
   6.158          /// <returns>The user ID (Outlook EntryID) for the given address</returns>
   6.159          internal string GetUserId(string address,
   6.160 -                                  Outlook.ContactItem contact)
   6.161 +                                  Outlook.ContactItem contact = null)
   6.162          {
   6.163              string id = null;
   6.164              Outlook.Folder contactFolder = null;
   6.165 @@ -689,7 +623,7 @@
   6.166                          // Check if the address is myself
   6.167                          if (PEPIdentity.GetIsOwnIdentity(address))
   6.168                          {
   6.169 -                            id = "pEp_own_userId"; // Alternatively, null or empty could be used
   6.170 +                            id = PEPSettings.PEP_OWN_USER_ID;
   6.171                              this.userIdCache[address] = id;
   6.172                          }
   6.173                      }
   6.174 @@ -700,8 +634,7 @@
   6.175                      {
   6.176                          try
   6.177                          {
   6.178 -                            contactFolder = (Outlook.Folder)contact.Parent;
   6.179 -                            id = contactFolder.StoreID.ToUpperInvariant() + "_" + contact.EntryID.ToUpperInvariant();
   6.180 +                            id = contact.EntryID;
   6.181                              this.userIdCache[address] = id;
   6.182                          }
   6.183                          catch
   6.184 @@ -709,11 +642,6 @@
   6.185                              Log.Error("GetUserId: Attempted to use contact but failed.");
   6.186                          }
   6.187                      }
   6.188 -
   6.189 -                    /* If no user ID is found at this point, return null.
   6.190 -                     * The engine supports 'virtual users' that are only uniquely identified by address.
   6.191 -                     * Virtual users will be automatically upgraded if a contact is ever created for the email address.
   6.192 -                     */
   6.193                  }
   6.194              }
   6.195              catch (Exception ex)
     7.1 --- a/UI/HandshakeDialog.xaml.cs	Mon Feb 12 16:40:36 2018 +0100
     7.2 +++ b/UI/HandshakeDialog.xaml.cs	Thu Feb 15 13:31:50 2018 +0100
     7.3 @@ -165,8 +165,6 @@
     7.4  
     7.5                      /* Update the identities to get fingerprints and add to list. If a recipient is an own identity,
     7.6                       * don't add it to the list, as we don't do handshakes with own identities.
     7.7 -                     * Recipients without color are stored temporarily in a separate list and are appended to
     7.8 -                     * the end of the actual recipients list, as they are hidden by default.
     7.9                       */
    7.10                      foreach (var recipient in recipients)
    7.11                      {