Merge with default COM-87
authorThomas
Mon, 30 Apr 2018 11:52:00 +0200
branchCOM-87
changeset 2859a19b5dbb271
parent 282 3b92433f8da7
parent 284 83ad8d765099
child 286 c6bf26cf7a08
Merge with default
CpEpEngine.cpp
pEpCOMServerAdapter.idl
     1.1 --- a/CpEpEngine.cpp	Thu Apr 26 15:30:43 2018 +0200
     1.2 +++ b/CpEpEngine.cpp	Mon Apr 30 11:52:00 2018 +0200
     1.3 @@ -3,6 +3,7 @@
     1.4  #include "stdafx.h"
     1.5  #include "CpEpEngine.h"
     1.6  #include <mutex>
     1.7 +#include "GateKeeper.h"
     1.8  
     1.9  using namespace std;
    1.10  using namespace pEp::utility;
    1.11 @@ -917,6 +918,57 @@
    1.12      return S_OK;
    1.13  }
    1.14  
    1.15 +STDMETHODIMP CpEpEngine::EncryptMessageAndAddPrivKey(TextMessage * src, TextMessage * dst, BSTR to_fpr, pEpEncryptFlags flags, pEpEncFormat encFormat)
    1.16 +{
    1.17 +    assert(src);
    1.18 +    assert(dst);
    1.19 +    assert(to_fpr);
    1.20 +
    1.21 +    if (!(src && dst))
    1.22 +        return E_INVALIDARG;
    1.23 +
    1.24 +    ::message *_src = text_message_to_C(src);
    1.25 +
    1.26 +    _PEP_enc_format _encFormat = (_PEP_enc_format)encFormat;
    1.27 +
    1.28 +    // COM-19: Initialize msg_dst to NULL, or we end up calling
    1.29 +    // free_message() below with a pointer to random garbage in
    1.30 +    // case of an error in encrypt_message().
    1.31 +    ::message *msg_dst = NULL;
    1.32 +
    1.33 +    string _to_fpr = utf8_string(to_fpr);
    1.34 +                                                    // _PEP_enc_format used to be intentionally hardcoded to PEP_enc_PEP:
    1.35 +                                                    // Since COM-74, this has been changed to an explicit parameter, to allow the engine to attach
    1.36 +                                                    // the keys and headers to outgoing, unencrypted messages.
    1.37 +    PEP_encrypt_flags_t engineFlags = (PEP_encrypt_flags_t)flags;
    1.38 +    PEP_STATUS status = ::encrypt_message_and_add_priv_key(get_session(), _src, &msg_dst, _to_fpr.c_str(), _encFormat, engineFlags);
    1.39 +
    1.40 +    if (status == PEP_STATUS_OK)
    1.41 +        text_message_from_C(dst, msg_dst);
    1.42 +    else
    1.43 +        text_message_from_C(dst, _src);
    1.44 +
    1.45 +    ::free_message(msg_dst);
    1.46 +    ::free_message(_src);
    1.47 +
    1.48 +    if (status == PEP_OUT_OF_MEMORY)
    1.49 +        return E_OUTOFMEMORY;
    1.50 +
    1.51 +    // COM-41: Enhanced PEP status handling
    1.52 +    if ((status != PEP_STATUS_OK) && (status < PEP_UNENCRYPTED || status >= PEP_TRUSTWORD_NOT_FOUND))
    1.53 +        return FAIL("Failure to encrypt message", status);
    1.54 +
    1.55 +    // Statii like PEP_UNENCRYPTED due to no private key
    1.56 +    // should not be a catastrophic failure here. Using S_FALSE
    1.57 +    // still allows clients to differentiate with S_OK,
    1.58 +    // although this does not work out of the box with
    1.59 +    // the standard .NET mapping of COM.
    1.60 +    if (status != PEP_STATUS_OK)
    1.61 +        return S_FALSE;
    1.62 +
    1.63 +    return S_OK;
    1.64 +}
    1.65 +
    1.66  STDMETHODIMP CpEpEngine::EncryptMessageForSelf(pEpIdentity * targetId, TextMessage * src,
    1.67      /* [in] */ SAFEARRAY *extra, TextMessage * dst, pEpEncryptFlags flags)
    1.68  {
    1.69 @@ -1424,6 +1476,20 @@
    1.70      return msg;
    1.71  }
    1.72  
    1.73 +// Force an update check now
    1.74 +STDMETHODIMP CpEpEngine::UpdateNow()
    1.75 +{
    1.76 +    try
    1.77 +    {
    1.78 +        ::pEp::GateKeeper::update_now();
    1.79 +    }
    1.80 +    catch (bad_alloc&) {
    1.81 +        return E_OUTOFMEMORY;
    1.82 +    }
    1.83 +    catch (exception& ex) {
    1.84 +        return FAIL(ex.what());;
    1.85 +    }
    1.86 +}
    1.87  
    1.88  // Event callbacks
    1.89  
     2.1 --- a/CpEpEngine.h	Thu Apr 26 15:30:43 2018 +0200
     2.2 +++ b/CpEpEngine.h	Mon Apr 30 11:52:00 2018 +0200
     2.3 @@ -240,6 +240,13 @@
     2.4          /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
     2.5          /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
     2.6  
     2.7 +    STDMETHOD(EncryptMessageAndAddPrivKey)(
     2.8 +        /* [in] */ struct TextMessage *src,
     2.9 +        /* [out] */ struct TextMessage *dst,
    2.10 +        /* [in] */ BSTR to_fpr,
    2.11 +        /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
    2.12 +        /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
    2.13 +
    2.14      STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
    2.15      STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
    2.16      STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
    2.17 @@ -263,7 +270,8 @@
    2.18      STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
    2.19  	STDMETHOD(SetOwnKey)(pEpIdentity * ident, BSTR fpr, struct pEpIdentity *result);
    2.20  
    2.21 -
    2.22 +    // Trigger an immediate update
    2.23 +    STDMETHOD(UpdateNow)();
    2.24  protected:
    2.25      HRESULT Fire_MessageToSend(
    2.26          /* [in] */ struct TextMessage *msg);
     3.1 --- a/GateKeeper.cpp	Thu Apr 26 15:30:43 2018 +0200
     3.2 +++ b/GateKeeper.cpp	Mon Apr 30 11:52:00 2018 +0200
     3.3 @@ -109,6 +109,9 @@
     3.4  }
     3.5  
     3.6  namespace pEp {
     3.7 +    std::mutex GateKeeper::update_wait_mtx;
     3.8 +    std::condition_variable GateKeeper::update_wait_var;
     3.9 +    bool GateKeeper::update_wait_forced = false;
    3.10  
    3.11      const LPCTSTR GateKeeper::plugin_reg_path = _T("Software\\Microsoft\\Office\\Outlook\\Addins\\pEp");
    3.12      const LPCTSTR GateKeeper::plugin_reg_value_name = _T("LoadBehavior");
    3.13 @@ -116,7 +119,7 @@
    3.14  
    3.15      const time_t GateKeeper::cycle = 7200;   // 7200 sec is 2 h
    3.16      const time_t GateKeeper::fraction = 10;  // first update is at 10% of cycle
    3.17 -    const DWORD GateKeeper::waiting = 10000; // 10000 ms is 10 sec
    3.18 +    const chrono::seconds GateKeeper::waiting = 10s; //  10 sec
    3.19  
    3.20      GateKeeper::GateKeeper(CpEpCOMServerAdapterModule * self)
    3.21          : _self(self), now(time(NULL)), next(now /*+ time_diff()*/), hkUpdater(NULL),
    3.22 @@ -174,13 +177,28 @@
    3.23              now = time(NULL);
    3.24              assert(now != -1);
    3.25  
    3.26 -            if (now > next) {
    3.27 +            bool force_check;
    3.28 +            // We need to sleep, but we should be interruptible by the update_now() method.
    3.29 +            {
    3.30 +                std::unique_lock<std::mutex> guard(GateKeeper::update_wait_mtx);
    3.31 +                GateKeeper::update_wait_var.wait_for(guard, waiting);
    3.32 +                force_check = GateKeeper::update_wait_forced;
    3.33 +                GateKeeper::update_wait_forced = false;
    3.34 +            }
    3.35 +
    3.36 +            if (force_check || now > next) {
    3.37                  next = now + GateKeeper::cycle;
    3.38                  keep_updated();
    3.39              }
    3.40 +        }
    3.41 +    }
    3.42  
    3.43 -            Sleep(waiting);
    3.44 -        }
    3.45 +    void GateKeeper::update_now() 
    3.46 +    {
    3.47 +        // Signal the GateKeeper thread that we need to check for updates now.
    3.48 +        std::unique_lock<std::mutex> guard(GateKeeper::update_wait_mtx);
    3.49 +        GateKeeper::update_wait_forced = true;
    3.50 +        GateKeeper::update_wait_var.notify_all();
    3.51      }
    3.52  
    3.53      void GateKeeper::keep_plugin()
     4.1 --- a/GateKeeper.h	Thu Apr 26 15:30:43 2018 +0200
     4.2 +++ b/GateKeeper.h	Mon Apr 30 11:52:00 2018 +0200
     4.3 @@ -31,6 +31,8 @@
     4.4  
     4.5          void keep();
     4.6  
     4.7 +        static void update_now();
     4.8 +
     4.9      protected:
    4.10          static const LPCTSTR plugin_reg_path;
    4.11          static const LPCTSTR plugin_reg_value_name;
    4.12 @@ -38,7 +40,7 @@
    4.13  
    4.14          static const time_t cycle;
    4.15          static const time_t fraction;
    4.16 -        static const DWORD waiting;
    4.17 +        static const std::chrono::seconds waiting;
    4.18  
    4.19          static time_t time_diff();
    4.20  
    4.21 @@ -65,5 +67,9 @@
    4.22          BCRYPT_ALG_HANDLE hRSA;
    4.23  
    4.24          CpEpCOMServerAdapterModule * _self;
    4.25 +
    4.26 +        static std::mutex update_wait_mtx;
    4.27 +        static std::condition_variable update_wait_var;
    4.28 +        static bool update_wait_forced;
    4.29      };
    4.30  }
     5.1 --- a/pEpCOMServerAdapter.idl	Thu Apr 26 15:30:43 2018 +0200
     5.2 +++ b/pEpCOMServerAdapter.idl	Mon Apr 30 11:52:00 2018 +0200
     5.3 @@ -396,7 +396,7 @@
     5.4      [id(34)] HRESULT EncryptMessageForSelf(
     5.5          [in] struct pEpIdentity* targetId,
     5.6          [in] struct TextMessage* src,
     5.7 -        [in] SAFEARRAY(BSTR) extra,
     5.8 +        [in] SAFEARRAY(BSTR) extra, // Fingerprints for extra keys for encryption.
     5.9          [out] struct TextMessage* dst,
    5.10          [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags
    5.11      );
    5.12 @@ -414,11 +414,24 @@
    5.13  
    5.14  	// mark imported keys as trusted
    5.15  
    5.16 -	HRESULT SetOwnKey(
    5.17 +	[id(38)] HRESULT SetOwnKey(
    5.18  		[in] struct pEpIdentity * ident,
    5.19  		[in] BSTR fpr,
    5.20  		[out, retval] struct pEpIdentity * result
    5.21  	);
    5.22 +
    5.23 +    [id(39)] HRESULT EncryptMessageAndAddPrivKey(
    5.24 +        [in] struct TextMessage *src,
    5.25 +        [out] struct TextMessage * dst,
    5.26 +        [in] BSTR to_fpr,
    5.27 +        [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags,
    5.28 +        // Use pEpEncFormat.pEpEncNone for unencrypted, outgoing messages.
    5.29 +        // Default is pEpEncFormat.pEpEncPep, all other formats are only 
    5.30 +        // for compatibility and not intended for normal use.
    5.31 +        [in, defaultvalue(pEpEncPep)] pEpEncFormat encFormat);
    5.32 +
    5.33 +    // Trigger an immediate update check.
    5.34 +    [id(40)] HRESULT UpdateNow();
    5.35  };
    5.36  
    5.37  [