AdapterExtensions.cs
author Thomas
Thu, 04 Jul 2019 16:50:28 +0200
branchtest_sync_folder
changeset 2677 0df7d44b2439
parent 2170 d51dcaf9df57
child 2183 74999a6fa16a
child 2875 6b75679c8b61
permissions -rw-r--r--
Move sync messages to inbox/pEp folder to hide them
Dean@1341
     1
´╗┐using pEpCOMServerAdapterLib;
Dean@1430
     2
using System;
Dean@1341
     3
using System.Collections.Generic;
Dean@1430
     4
using System.Runtime.InteropServices;
Dean@1341
     5
Dean@1341
     6
namespace pEp
Dean@1341
     7
{
Dean@1341
     8
    /// <summary>
Dean@1341
     9
    /// Contains extensions for the COM adapter as well as utility methods.
Dean@1341
    10
    /// </summary>
Dean@1341
    11
    internal static class AdapterExtensions
Dean@1341
    12
    {
Dean@1341
    13
        private static readonly Dictionary<pEpRating, pEpColor> colorRatingCache = new Dictionary<pEpRating, pEpColor>();
Dean@1341
    14
Dean@1341
    15
        /**************************************************************
Dean@1341
    16
         * 
Dean@1430
    17
         * Wrapper Methods
Dean@1430
    18
         * 
Dean@1430
    19
         *************************************************************/
Dean@1430
    20
Dean@1430
    21
        /// <summary>
Dean@1430
    22
        /// Gets the Trustwords for the two given identities.
Dean@1430
    23
        /// This will never return null.
Dean@1430
    24
        /// </summary>
Dean@1430
    25
        /// <param name="id1">The first identity to get Trustwords for.</param>
Dean@1430
    26
        /// <param name="id2">The second identity to get Trustwords for.</param>
Dean@1430
    27
        /// <param name="lang">The language to calculate the Trustwords in.</param>
Dean@1430
    28
        /// <param name="full">True to return full-form trustwords, False to return short-form.</param>
Dean@1430
    29
        /// <returns>The Trustwords for the two given identities.</returns>
Dean@1430
    30
        public static string GetTrustwords(PEPIdentity id1,
Dean@1430
    31
                                           PEPIdentity id2,
Dean@1430
    32
                                           string lang = PEPSettings.CULTURE_CODE_DEFAULT,
Dean@1430
    33
                                           bool full = false)
Dean@1430
    34
        {
Thomas@2170
    35
            string trustwords = null;
Dean@1430
    36
Dean@1430
    37
            try
Dean@1430
    38
            {
Thomas@2170
    39
                if (id1?.Fingerprint?.Equals(id2?.Fingerprint) == true)
Thomas@2170
    40
                {
Thomas@2170
    41
                    Log.Error("GetTrustwords: Identities have same fingerprint. Cannot make handshake between same identities.");
Thomas@2170
    42
                }
Thomas@2170
    43
                else
Thomas@2170
    44
                {
Thomas@2170
    45
                    trustwords = ThisAddIn.PEPEngine.GetTrustwords(id1.ToCOMType(), id2.ToCOMType(), lang, full);
Thomas@2170
    46
                }
Dean@1430
    47
            }
Dean@1430
    48
            catch (COMException ex)
Dean@1430
    49
            {
Dean@1430
    50
                trustwords = string.Empty;
Thomas@2166
    51
                Log.Error("GetTrustwords: Failure occured with account: id1 - " + id1?.Address+ ", id2 - " + id2?.Address + ". " + ex.ToString());
Dean@1430
    52
            }
Dean@1430
    53
            catch (Exception ex)
Dean@1430
    54
            {
Dean@1430
    55
                trustwords = string.Empty;
Thomas@2166
    56
                Log.Error("GetTrustwords: Failure occured with account: id1 - " + id1?.Address + ", id2 - " + id2?.Address + ". " + ex.ToString());
Dean@1430
    57
            }
Dean@1430
    58
Dean@1430
    59
            return (trustwords ?? string.Empty);
Dean@1430
    60
        }
Dean@1430
    61
Thomas@1692
    62
        /// <summary>
Thomas@1692
    63
        /// Reevaluates the rating of the given PEPMessage.
Thomas@1692
    64
        /// </summary>
Thomas@1692
    65
        /// <param name="message">The message to reevaluate.</param>
Thomas@1692
    66
        /// <param name="originalRating">The original rating of the message.</param>
Thomas@1776
    67
        /// <param name="keyList">The key list of the message.</param>
Thomas@1692
    68
        /// <returns>The reevaluated rating.</returns>
Thomas@1776
    69
        public static pEpRating ReevaluateMessageRating(PEPMessage message, pEpRating? originalRating = null, string[] keyList = null)
Thomas@1692
    70
        {
Thomas@1973
    71
            pEpRating rating = originalRating ?? message.Rating;
Thomas@1692
    72
Thomas@1779
    73
            if (message != null)
Thomas@1692
    74
            {
Thomas@1692
    75
                try
Thomas@1692
    76
                {
Thomas@1692
    77
                    TextMessage src = message.ToCOMType();
Thomas@1776
    78
Thomas@1776
    79
                    // If no keylist was explicitly passed, use the one stored with the message
Thomas@1780
    80
                    // Note: this can still be null in case of unencrypted emails
Thomas@1692
    81
                    if (keyList == null)
Thomas@1692
    82
                    {
Thomas@1779
    83
                        keyList = message?.KeyList?.Split(',');
Thomas@1692
    84
                    }
Thomas@1692
    85
Thomas@1973
    86
                    if (rating != pEpRating.pEpRatingUndefined)
Thomas@1973
    87
                    {
Thomas@1973
    88
                        rating = ThisAddIn.PEPEngine.ReEvaluateMessageRating(src, keyList, rating);
Thomas@1973
    89
                    }
Thomas@1692
    90
                }
Thomas@1776
    91
                catch (Exception ex)
Thomas@1692
    92
                {
Thomas@1973
    93
                    rating = pEpRating.pEpRatingUndefined;
Thomas@1776
    94
                    Log.Error("ReevaluateMessageRating: Error reevaluating rating. " + ex.ToString());
Thomas@1692
    95
                }
Thomas@1692
    96
            }
Thomas@1692
    97
Thomas@1973
    98
            return rating;
Thomas@1692
    99
        }
Thomas@1692
   100
Thomas@1924
   101
        /// <summary>
Thomas@1924
   102
        /// Reevaluates the rating of a forcefully protected message. This uses the From identity's
Thomas@1924
   103
        /// fingerprint and sets the message's rating manually to Reliable before reevaluation.
Thomas@1924
   104
        /// </summary>
Thomas@1924
   105
        /// <param name="message">The message to reevaluate</param>
Thomas@1924
   106
        /// <returns>The reevaluated rating</returns>
Thomas@1924
   107
        public static pEpRating ReevaluateFPPMessageRating(PEPMessage message)
Thomas@1924
   108
        {
Thomas@1924
   109
            pEpRating reevaluatedRating;
Thomas@1924
   110
Thomas@1924
   111
            // Add the sender's fingerprint to the message's key list
Thomas@1924
   112
            try
Thomas@1924
   113
            {
Thomas@1924
   114
                pEpIdentity ident = ThisAddIn.PEPEngine.UpdateIdentity(message.From.ToCOMType());
Thomas@1924
   115
                if (string.IsNullOrEmpty(message.KeyList))
Thomas@1924
   116
                {
Thomas@1924
   117
                    message.KeyList = ident.fpr;
Thomas@1924
   118
                }
Thomas@1924
   119
                else
Thomas@1924
   120
                {
Thomas@1924
   121
                    message.KeyList.Insert(0, (ident.fpr + ","));
Thomas@1924
   122
                }
Thomas@1924
   123
            }
Thomas@1924
   124
            catch (Exception ex)
Thomas@1924
   125
            {
Thomas@1924
   126
                Log.Error("ReevaluateFPPMessageRating: Error adding key list to message. " + ex.ToString());
Thomas@1924
   127
            }
Thomas@1924
   128
Thomas@1924
   129
            // Set message rating to reliable if no other rating has been calculated
Thomas@1924
   130
            if ((message.Rating == pEpRating.pEpRatingUnencrypted) ||
Thomas@1924
   131
                (message.Rating == pEpRating.pEpRatingUndefined))
Thomas@1924
   132
            {
Thomas@1924
   133
                message.Rating = pEpRating.pEpRatingReliable;
Thomas@1924
   134
            }
Thomas@1924
   135
Thomas@1924
   136
            // Reevaluate the message's rating
Thomas@1924
   137
            reevaluatedRating = AdapterExtensions.ReevaluateMessageRating(message, message.Rating);
Thomas@1924
   138
Thomas@1924
   139
            // Return the new rating if it was successfully updated, otherwise the original
Thomas@1924
   140
            return (reevaluatedRating != pEpRating.pEpRatingUndefined) ? reevaluatedRating : message.Rating;
Thomas@1924
   141
        }
Thomas@1776
   142
Dean@1430
   143
        /**************************************************************
Dean@1430
   144
         * 
Dean@1504
   145
         * pEpIdentity Extensions
Dean@1504
   146
         * 
Dean@1504
   147
         *************************************************************/
Dean@1504
   148
Dean@1504
   149
        /// <summary>
Dean@1504
   150
        /// Gets whether the pEp identity is flagged as a member of an existing device group.
Dean@1504
   151
        /// </summary>
Dean@1504
   152
        /// <param name="identity">The pEp identity to process with.</param>
Dean@1504
   153
        /// <returns>True if flagged as a member of a device group, otherwise false.</returns>
Dean@1504
   154
        public static bool GetIsInDeviceGroup(this pEpIdentity identity)
Dean@1504
   155
        {
Dean@1504
   156
            return (identity.Flags.HasFlag(pEpIdentityFlags.pEpIdfDevicegroup));
Dean@1504
   157
        }
Dean@1504
   158
Dean@1504
   159
        /// <summary>
Dean@1504
   160
        /// Gets whether the pEp identity is flagged as a list.
Dean@1504
   161
        /// Email lists should not be used for syncronization.
Dean@1504
   162
        /// </summary>
Dean@1504
   163
        /// <param name="identity">The pEp identity to process with.</param>
Dean@1504
   164
        /// <returns>True if flagged as a list, otherwise false.</returns>
Dean@1504
   165
        public static bool GetIsList(this pEpIdentity identity)
Dean@1504
   166
        {
Dean@1504
   167
            return (identity.Flags.HasFlag(pEpIdentityFlags.pEpIdfList));
Dean@1504
   168
        }
Dean@1504
   169
Dean@1504
   170
        /// <summary>
Dean@1504
   171
        /// Gets whether the pEp identity is flagged to be included in device synchronization.
Dean@1504
   172
        /// </summary>
Dean@1504
   173
        /// <param name="identity">The pEp identity to process with.</param>
Dean@1504
   174
        /// <returns>True if flagged for synchronization, otherwise false.</returns>
Dean@1504
   175
        public static bool GetIsSyncEnabled(this pEpIdentity identity)
Dean@1504
   176
        {
Dean@1504
   177
            return (!identity.Flags.HasFlag(pEpIdentityFlags.pEpIdfNotForSync));
Dean@1504
   178
        }
Dean@1504
   179
Dean@1504
   180
        /**************************************************************
Dean@1504
   181
         * 
Dean@1341
   182
         * pEpRating Extensions
Dean@1341
   183
         * 
Dean@1341
   184
         *************************************************************/
Dean@1341
   185
Dean@1341
   186
        /// <summary>
Dean@1341
   187
        /// Gets the pEp color for the pEp rating.
Dean@1341
   188
        /// </summary>
Dean@1341
   189
        /// <param name="rating">The pEp rating to process with.</param>
Dean@1341
   190
        /// <returns>The pEp color corresponding to the rating.</returns>
Dean@1341
   191
        public static pEpColor ToColor(this pEpRating rating)
Dean@1341
   192
        {
Dean@1341
   193
            pEpColor result;
Dean@1341
   194
Dean@1341
   195
            // Lookup in cache
Dean@1341
   196
            if (colorRatingCache.TryGetValue(rating, out result))
Dean@1341
   197
            {
Dean@1341
   198
                return result;
Dean@1341
   199
            }
Dean@1341
   200
Dean@1341
   201
            // Slowly ask the engine
Dean@1341
   202
            result = ThisAddIn.PEPEngine.ColorFromRating(rating);
Dean@1341
   203
            colorRatingCache[rating] = result;
Dean@1341
   204
Dean@1341
   205
            return result;
Dean@1341
   206
        }
Dean@1341
   207
Dean@1341
   208
        /// <summary>
Dean@1341
   209
        /// Gets the string representing the pEp rating as used by the pEp engine.
Dean@1341
   210
        /// It is important this is not the enumeration string as this value is shared among pEp clients.
Dean@1341
   211
        /// This string is what will be stored as an optional header field.
Dean@1341
   212
        /// </summary>
Dean@1341
   213
        /// <remarks>
Dean@1341
   214
        /// Note: This is implemented here instead of the adapter for performance reasons
Dean@1341
   215
        /// </remarks>
Dean@1341
   216
        /// <param name="rating">The pEp rating to process with.</param>
Dean@1341
   217
        /// <returns>The string corresponding to the rating as defined by the pEp engine.</returns>
Dean@1341
   218
        public static string ToEngineString(this pEpRating rating)
Dean@1341
   219
        {
Dean@1341
   220
            // Note: See engine code for 'rating_to_string' in 'message_api.c'
Dean@1341
   221
            switch (rating)
Dean@1341
   222
            {
Dean@1341
   223
                case pEpRating.pEpRatingCannotDecrypt:
Dean@1341
   224
                    return "cannot_decrypt";
Dean@1341
   225
                case pEpRating.pEpRatingHaveNoKey:
Dean@1341
   226
                    return "have_no_key";
Dean@1341
   227
                case pEpRating.pEpRatingUnencrypted:
Dean@1341
   228
                    return "unencrypted";
Dean@1341
   229
                case pEpRating.pEpRatingUnencryptedForSome:
Dean@1341
   230
                    return "unencrypted_for_some";
Dean@1341
   231
                case pEpRating.pEpRatingUnreliable:
Dean@1341
   232
                    return "unreliable";
Dean@1341
   233
                case pEpRating.pEpRatingReliable:
Dean@1341
   234
                    return "reliable";
Dean@1341
   235
                case pEpRating.pEpRatingTrusted:
Dean@1341
   236
                    return "trusted";
Dean@1341
   237
                case pEpRating.pEpRatingTrustedAndAnonymized:
Dean@1341
   238
                    return "trusted_and_anonymized";
Dean@1341
   239
                case pEpRating.pEpRatingFullyAnonymous:
Dean@1341
   240
                    return "fully_anonymous";
Dean@1341
   241
                case pEpRating.pEpRatingMistrust:
Dean@1341
   242
                    return "mistrust";
Dean@1341
   243
                case pEpRating.pEpRatingB0rken:
Dean@1341
   244
                    return "b0rken";
Dean@1341
   245
                case pEpRating.pEpRatingUnderAttack:
Dean@1341
   246
                    return "under_attack";
Dean@1341
   247
                default:
Dean@1341
   248
                    return "undefined";
Dean@1341
   249
            }
Dean@1341
   250
        }
Dean@1341
   251
Dean@1341
   252
        /// <summary>
Dean@1341
   253
        /// Parses the given string as a pEp rating ignoring character case.
Dean@1341
   254
        /// This will support both enumeration values defined by the adapter, as well as the engine
Dean@1341
   255
        /// string definitions from .ToEngineString().
Dean@1341
   256
        /// </summary>
Dean@1341
   257
        /// <remarks>
Dean@1341
   258
        /// Note: This is implemented here instead of the adapter for performance reasons.
Dean@1341
   259
        /// </remarks>
Dean@1341
   260
        /// <param name="str">The string to parse as a pEp rating.</param>
Dean@1341
   261
        /// <returns>The pEp rating corresponding to the given string, otherwise 'Undefined'.</returns>
Dean@1341
   262
        public static pEpRating ParseRatingString(string str)
Dean@1341
   263
        {
Dean@1341
   264
            pEpRating rating = pEpRating.pEpRatingUndefined;
Dean@1341
   265
Dean@1341
   266
            if (str != null)
Dean@1341
   267
            {
Dean@1341
   268
                switch (str.Trim().ToUpperInvariant())
Dean@1341
   269
                {
Dean@1341
   270
                    case "CANNOT_DECRYPT":
Dean@1341
   271
                    case "PEPRATINGCANNOTDECRYPT":
Dean@1341
   272
                        return pEpRating.pEpRatingCannotDecrypt;
Dean@1341
   273
                    case "HAVE_NO_KEY":
Dean@1341
   274
                    case "PEPRATINGHAVENOKEY":
Dean@1341
   275
                        return pEpRating.pEpRatingHaveNoKey;
Dean@1341
   276
                    case "UNENCRYPTED":
Dean@1341
   277
                    case "PEPRATINGUNENCRYPTED":
Dean@1341
   278
                        return pEpRating.pEpRatingUnencrypted;
Dean@1341
   279
                    case "UNENCRYPTED_FOR_SOME":
Dean@1341
   280
                    case "PEPRATINGUNENCRYPTEDFORSOME":
Dean@1341
   281
                        return pEpRating.pEpRatingUnencryptedForSome;
Dean@1341
   282
                    case "UNRELIABLE":
Dean@1341
   283
                    case "PEPRATINGUNRELIABLE":
Dean@1341
   284
                        return pEpRating.pEpRatingUnreliable;
Dean@1341
   285
                    case "RELIABLE":
Dean@1341
   286
                    case "PEPRATINGRELIABLE":
Dean@1341
   287
                        return pEpRating.pEpRatingReliable;
Dean@1341
   288
                    case "TRUSTED":
Dean@1341
   289
                    case "PEPRATINGTRUSTED":
Dean@1341
   290
                        return pEpRating.pEpRatingTrusted;
Dean@1341
   291
                    case "TRUSTED_AND_ANONYMIZED":
Dean@1341
   292
                    case "PEPRATINGTRUSTEDANDANONYMIZED":
Dean@1341
   293
                        return pEpRating.pEpRatingTrustedAndAnonymized;
Dean@1341
   294
                    case "FULLY_ANONYMOUS":
Dean@1341
   295
                    case "PEPRATINGFULLYANONYMOUS":
Dean@1341
   296
                        return pEpRating.pEpRatingFullyAnonymous;
Dean@1341
   297
                    case "MISTRUST":
Dean@1341
   298
                    case "PEPRATINGMISTRUST":
Dean@1341
   299
                        return pEpRating.pEpRatingMistrust;
Dean@1341
   300
                    case "B0RKEN":
Dean@1341
   301
                    case "PEPRATINGB0RKEN":
Dean@1341
   302
                        return pEpRating.pEpRatingB0rken;
Dean@1341
   303
                    case "UNDER_ATTACK":
Dean@1341
   304
                    case "PEPRATINGUNDERATTACK":
Dean@1341
   305
                        return pEpRating.pEpRatingUnderAttack;
Dean@1341
   306
                    default:
Dean@1341
   307
                        return pEpRating.pEpRatingUndefined;
Dean@1341
   308
                }
Dean@1341
   309
            }
Dean@1341
   310
Dean@1341
   311
            return (rating);
Dean@1341
   312
        }
Dean@1341
   313
    }
Dean@1341
   314
}