From bcbe7bc1ffdba726b9772f63f00219931be1c552 Mon Sep 17 00:00:00 2001 From: Markus Schaber Date: Thu, 26 May 2016 00:11:36 +0200 Subject: [PATCH 1/5] Experimental implementation of events via explicit callback interface --- CpEpEngine.cpp | 68 +++++++++++++ CpEpEngine.h | 44 +++++++++ _IpEpEngineEvents_CP.h | 54 ----------- pEpCOMServerAdapter.idl | 31 ++++-- pEpCOMServerAdapter.vcxproj | 2 +- pEpCOMServerAdapter.vcxproj.filters | 2 +- pEpComAdapter.idl | 145 ---------------------------- 7 files changed, 138 insertions(+), 208 deletions(-) delete mode 100644 pEpComAdapter.idl diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index 5acd1f5..c326b1e 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -811,6 +811,11 @@ STDMETHODIMP CpEpEngine::myself(struct pEp_identity_s *ident, struct pEp_identit if (_ident == NULL) return E_OUTOFMEMORY; + // DEBUG CODE - REMOVE BEFORE RELEASE! + //sync_handshake_result_s handshakeResult; + // + //HRESULT res = Fire_ShowHandshake(ident, result, &handshakeResult); + PEP_STATUS status = ::myself(get_session(), _ident); if (status == PEP_STATUS_OK) { @@ -1244,3 +1249,66 @@ STDMETHODIMP CpEpEngine::trust_personal_key(struct pEp_identity_s *ident, struct return S_OK; } + + +// Event callbacks + +STDMETHODIMP CpEpEngine::register_callbacks(IpEpEngineCallbacks* new_callbacks) +{ + callbacks cbs = get_callbacks(); + vector& vec = cbs; + + vec.push_back(new_callbacks); + new_callbacks->AddRef(); + + return S_OK; +} + +STDMETHODIMP CpEpEngine::unregister_callbacks(IpEpEngineCallbacks* obsolete_callbacks) +{ + callbacks cbs = get_callbacks(); + vector& vec = cbs; + + auto position = std::find(vec.begin(), vec.end(), obsolete_callbacks); + if (position != vec.end()) { + vec.erase(position); + obsolete_callbacks->Release(); + return S_OK; + } + + return S_FALSE; +} + +HRESULT CpEpEngine::Fire_MessageToSend(text_message * msg) +{ + callbacks cbs = get_callbacks(); + vector& vec = cbs; + + assert(msg); + + for (auto it = vec.begin(); it != vec.end(); ++it) + { + auto res = (*it)->MessageToSend(msg); + if (res != S_OK) + return res; + } + return S_OK; +} + +HRESULT CpEpEngine::Fire_ShowHandshake(pEp_identity_s * self, pEp_identity_s * partner, sync_handshake_result_s * result) +{ + callbacks cbs = get_callbacks(); + vector& vec = cbs; + + assert(self); + assert(partner); + assert(result); + + for (auto it = vec.begin(); it != vec.end(); ++it) + { + auto res = (*it)->ShowHandshake(self, partner, result); + if (res != S_OK) + return res; + } + return S_OK; +} diff --git a/CpEpEngine.h b/CpEpEngine.h index a577afd..0b08d11 100644 --- a/CpEpEngine.h +++ b/CpEpEngine.h @@ -107,6 +107,34 @@ protected: return session(this); } + class callbacks + { + private: + CpEpEngine *me; + + public: + callbacks(CpEpEngine *myself) + { + me = myself; + me->callback_mutex.lock(); + } + + ~callbacks() + { + me->callback_mutex.unlock(); + } + + operator vector& () + { + return me->callback_vector; + } + }; + + callbacks get_callbacks() + { + return callbacks(this); + } + typedef locked_queue identity_queue_t; static ::pEp_identity * retrieve_next_identity(void *management); static PEP_STATUS messageToSend(void *obj, const message *msg); @@ -130,6 +158,9 @@ private: thread *keymanagement_thread; bool verbose_mode; + mutex callback_mutex; + vector callback_vector; + public: // runtime config of the adapter @@ -190,6 +221,19 @@ public: STDMETHOD(outgoing_message_color)(text_message *msg, pEp_color * pVal); STDMETHOD(identity_color)(pEp_identity_s * ident, pEp_color * pVal); + // Event callbacks + + STDMETHOD(register_callbacks)(IpEpEngineCallbacks *new_callback); + STDMETHOD(unregister_callbacks)(IpEpEngineCallbacks *obsolete_callback); + +protected: + HRESULT Fire_MessageToSend( + /* [in] */ struct text_message *msg); + + HRESULT Fire_ShowHandshake( + /* [in] */ struct pEp_identity_s *self, + /* [in] */ struct pEp_identity_s *partner, + /* [retval][out] */ sync_handshake_result_s *result); }; OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine) diff --git a/_IpEpEngineEvents_CP.h b/_IpEpEngineEvents_CP.h index bb6d378..98784ea 100644 --- a/_IpEpEngineEvents_CP.h +++ b/_IpEpEngineEvents_CP.h @@ -5,59 +5,5 @@ class CProxy_IpEpEngineEvents : public ATL::IConnectionPointImpl { public: - HRESULT Fire_MessageToSend(text_message * msg) - { - HRESULT hr = S_OK; - T * pThis = static_cast(this); - int cConnections = m_vec.GetSize(); - - for (int iConnection = 0; iConnection < cConnections; iConnection++) - { - pThis->Lock(); - CComPtr punkConnection = m_vec.GetAt(iConnection); - pThis->Unlock(); - - IDispatch * pConnection = static_cast(punkConnection.p); - - if (pConnection) - { - CComVariant avarParams[1]; - avarParams[0] = msg; - CComVariant varResult; - - DISPPARAMS params = { avarParams, NULL, 1, 0 }; - hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL); - } - } - return hr; - } - HRESULT Fire_ShowHandshake(pEp_identity_s * self, pEp_identity_s * partner, sync_handshake_result_s * result) - { - HRESULT hr = S_OK; - T * pThis = static_cast(this); - int cConnections = m_vec.GetSize(); - - for (int iConnection = 0; iConnection < cConnections; iConnection++) - { - pThis->Lock(); - CComPtr punkConnection = m_vec.GetAt(iConnection); - pThis->Unlock(); - - IDispatch * pConnection = static_cast(punkConnection.p); - - if (pConnection) - { - CComVariant avarParams[3]; - avarParams[2] = self; - avarParams[1] = partner; - avarParams[0] = result; - CComVariant varResult; - - DISPPARAMS params = { avarParams, NULL, 3, 0 }; - hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL); - } - } - return hr; - } }; diff --git a/pEpCOMServerAdapter.idl b/pEpCOMServerAdapter.idl index 7d94351..f757469 100644 --- a/pEpCOMServerAdapter.idl +++ b/pEpCOMServerAdapter.idl @@ -7,6 +7,26 @@ import "oaidl.idl"; import "ocidl.idl"; + +typedef enum _sync_handshake_result_s { + SYNC_HANDSHAKE_CANCEL_S = -1, + SYNC_HANDSHAKE_ACCEPTED_S = 0, + SYNC_HANDSHAKE_REJECTED_S = 1 +} sync_handshake_result_s; + +[ + object, + uuid(3BA1B15B-27EF-433C-B780-0D08F46B0FF3), + oleautomation, + nonextensible, + pointer_default(unique) +] +interface IpEpEngineCallbacks : IUnknown { + [id(1)] HRESULT MessageToSend([in] struct text_message * msg); + [id(2)] HRESULT ShowHandshake([in] struct pEp_identity_s * self, [in] struct pEp_identity_s * partner, [out, retval] sync_handshake_result_s * result); +}; + + [ object, uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540), @@ -262,11 +282,10 @@ interface IpEpEngine : IUnknown { HRESULT outgoing_message_color([in] struct text_message *msg, [out, retval] pEp_color * pVal); HRESULT identity_color([in] struct pEp_identity_s * ident, [out, retval] pEp_color * pVal); - typedef enum _sync_handshake_result_s { - SYNC_HANDSHAKE_CANCEL_S = -1, - SYNC_HANDSHAKE_ACCEPTED_S = 0, - SYNC_HANDSHAKE_REJECTED_S = 1 - } sync_handshake_result_s; + + HRESULT register_callbacks([in] IpEpEngineCallbacks* new_callback); + + HRESULT unregister_callbacks([in] IpEpEngineCallbacks* obsolete_callback); }; [ @@ -283,8 +302,6 @@ library pEpCOMServerAdapterLib { properties: methods: - [id(1)] HRESULT MessageToSend([in] struct text_message * msg); - [id(2)] HRESULT ShowHandshake([in] struct pEp_identity_s * self, [in] struct pEp_identity_s * partner, [in,out] sync_handshake_result_s * result); }; [ uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2) diff --git a/pEpCOMServerAdapter.vcxproj b/pEpCOMServerAdapter.vcxproj index ad10899..52b53bb 100644 --- a/pEpCOMServerAdapter.vcxproj +++ b/pEpCOMServerAdapter.vcxproj @@ -159,7 +159,7 @@ echo "generating interop assembly $(TargetDir)pEpCOMServerAdapter.Interop.dll" - + diff --git a/pEpCOMServerAdapter.vcxproj.filters b/pEpCOMServerAdapter.vcxproj.filters index 796834a..e6e1bca 100644 --- a/pEpCOMServerAdapter.vcxproj.filters +++ b/pEpCOMServerAdapter.vcxproj.filters @@ -69,7 +69,7 @@ Header Files - + Generated Files diff --git a/pEpComAdapter.idl b/pEpComAdapter.idl deleted file mode 100644 index 5155bf0..0000000 --- a/pEpComAdapter.idl +++ /dev/null @@ -1,145 +0,0 @@ -// pEpComAdapter.idl : IDL source for pEpComAdapter -// - -// This file will be processed by the MIDL tool to -// produce the type library (pEpComAdapter.tlb) and marshalling code. - -import "oaidl.idl"; -import "ocidl.idl"; - -[ - object, - uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540), - oleautomation, - nonextensible, - pointer_default(unique) -] -interface IpEpEngine : IUnknown{ - typedef enum _pEp_STATUS { - pEp_STATUS_OK = 0, - - pEp_KEY_NOT_FOUND = 0x0201, - pEp_KEY_HAS_AMBIG_NAME = 0x0202, - pEp_GET_KEY_FAILED = 0x0203, - - pEp_UNENCRYPTED = 0x0400, - pEp_VERIFIED = 0x0401, - pEp_DECRYPTED = 0x0402, - pEp_DECRYPTED_AND_VERIFIED = 0x0403, - pEp_DECRYPT_WRONG_FORMAT = 0x0404, - pEp_DECRYPT_NO_KEY = 0x0405, - pEp_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406, - pEp_VERIFY_NO_KEY = 0x0407, - pEp_VERIFIED_AND_TRUSTED = 0x0408, - - pEp_ILLEGAL_VALUE = -4, - pEp_BUFFER_TOO_SMALL = -3, - pEp_OUT_OF_MEMORY = -2, - pEp_UNKNOWN_ERROR = -1 - } pEp_STATUS; - - [id(1)] HRESULT log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment); - [id(2)] HRESULT decrypt([in] BSTR ctext, [out] BSTR * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status); - [id(3)] HRESULT decrypt_b([in] BSTR ctext, [out] SAFEARRAY(BYTE) * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status); - [id(4)] HRESULT encrypt([in] SAFEARRAY(BSTR) key_list, [in] BSTR ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status); - [id(5)] HRESULT encrypt_b([in] SAFEARRAY(BSTR) key_list, [in] SAFEARRAY(BYTE) ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status); - [id(21)] HRESULT verify([in] BSTR text, [in] BSTR signature, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * verify_status); - [id(6)] HRESULT safeword([in] LONG value, [in, defaultvalue("en")] BSTR lang, [out, retval] BSTR * word); - [id(7)] HRESULT safewords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG max_words, [out, retval] BSTR * words); - - typedef enum _pEp_comm_type { - pEp_ct_unknown = 0, - - // range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable - - pEp_ct_no_encryption = 0x01, // generic - pEp_ct_no_encrypted_channel = 0x02, - pEp_ct_key_not_found = 0x03, - pEp_ct_key_expired = 0x04, - pEp_ct_key_revoked = 0x05, - pEp_ct_key_b0rken = 0x06, - pEp_ct_my_key_not_included = 0x09, - - pEp_ct_security_by_obscurity = 0x0a, - pEp_ct_b0rken_crypto = 0x0b, - pEp_ct_key_too_short = 0x0e, - - pEp_ct_compromized = 0x0f, // known compromized connection - - // range 0x10 to 0x3f: unconfirmed encryption - - pEp_ct_unconfirmed_encryption = 0x10, // generic - pEp_ct_OpenPGP_1024_RSA_unconfirmed = 0x11, // RSA 1024 is weak - pEp_ct_OpenPGP_unconfirmed = 0x3f, // key at least 2048 bit RSA - // or 1024 bit DSA - - // range 0x40 to 0x7f: unconfirmed encryption and anonymization - - pEp_ct_unconfirmed_enc_anon = 0x40, // generic - pEp_ct_pEp_unconfirmed = 0x7f, - - pEp_ct_confirmed = 0x80, // this bit decides if trust is confirmed - - // range 0x81 to 0x8f: reserved - // range 0x90 to 0xbf: confirmed encryption - - pEp_ct_confirmed_encryption = 0x90, // generic - pEp_ct_OpenPGP_1024_RSA = 0x91, // RSA 1024 is weak - pEp_ct_OpenPGP = 0xbf, // key at least 2048 bit RSA or 1024 bit DSA - - // range 0xc0 to 0xff: confirmed encryption and anonymization - - pEp_ct_confirmed_enc_anon = 0xc0, // generic - pEp_ct_pEp = 0xff - } pEp_comm_type; - - struct pEp_identity_s { - BSTR address; - BSTR fpr; - BSTR user_id; - BSTR username; - pEp_comm_type comm_type; - BSTR lang; - }; - - [id(8)] HRESULT get_identity([in] BSTR address, [out, retval] struct pEp_identity_s * ident); - [id(9)] HRESULT set_identity([in] struct pEp_identity_s * ident); - [id(10)] HRESULT generate_keypair([in] struct pEp_identity_s * ident, [out, retval] BSTR * fpr); - [id(11)] HRESULT delete_keypair([in] BSTR fpr); - [id(12)] HRESULT import_key([in] BSTR key_data); - [id(13)] HRESULT import_key_b([in] SAFEARRAY(BYTE) key_data); - [id(14)] HRESULT export_key([in] BSTR fpr, [out, retval] BSTR * key_data); - [id(15)] HRESULT recv_key([in] BSTR pattern); - [id(16)] HRESULT find_keys([in] BSTR pattern, [out, retval] SAFEARRAY(BSTR) * key_list); - [id(17)] HRESULT send_key([in] BSTR pattern); - - [id(19)] HRESULT examine_identity([in] struct pEp_identity_s * ident); - [id(20)] HRESULT examine_myself([in] struct pEp_identity_s * myself); - [id(22)] HRESULT myself([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result); - [id(23)] HRESULT update_identity([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result); -}; -[ - uuid(3EC2E1A4-40E8-48E4-A7B0-1876D34F9462), - version(1.0), -] -library pEpComAdapterLib -{ - importlib("stdole2.tlb"); - [ - uuid(B6BC9B8E-D9E2-4419-A3A4-7B4B58175549) - ] - dispinterface _IpEpEngineEvents - { - properties: - methods: - }; - [ - uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2) - ] - coclass pEpEngine - { - [default] interface IpEpEngine; - [default, source] dispinterface _IpEpEngineEvents; - }; -}; - From 17ac198b4b6f49b2b4c1b0f7b745cb0985185451 Mon Sep 17 00:00:00 2001 From: Markus Schaber Date: Sat, 28 May 2016 21:02:06 +0200 Subject: [PATCH 2/5] Debug / test code for events and callbacks. --- CpEpEngine.cpp | 6 ++++-- _IpEpEngineEvents_CP.h | 31 +++++++++++++++++++++++++++++++ pEpCOMServerAdapter.idl | 4 +++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index c326b1e..514c9a4 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -812,9 +812,11 @@ STDMETHODIMP CpEpEngine::myself(struct pEp_identity_s *ident, struct pEp_identit return E_OUTOFMEMORY; // DEBUG CODE - REMOVE BEFORE RELEASE! - //sync_handshake_result_s handshakeResult; + // sync_handshake_result_s handshakeResult; // - //HRESULT res = Fire_ShowHandshake(ident, result, &handshakeResult); + // HRESULT res = Fire_ShowHandshake(ident, result, &handshakeResult); + // + // HRESULT res2 = Fire_TestEvent(15, _bstr_t( "hallo")); PEP_STATUS status = ::myself(get_session(), _ident); diff --git a/_IpEpEngineEvents_CP.h b/_IpEpEngineEvents_CP.h index 98784ea..c9f731e 100644 --- a/_IpEpEngineEvents_CP.h +++ b/_IpEpEngineEvents_CP.h @@ -5,5 +5,36 @@ class CProxy_IpEpEngineEvents : public ATL::IConnectionPointImpl { public: + + /* Test code - remove before shipping + HRESULT Fire_TestEvent(LONG test, BSTR testtest) + { + HRESULT hr = S_OK; + T * pThis = static_cast(this); + int cConnections = m_vec.GetSize(); + + for (int iConnection = 0; iConnection < cConnections; iConnection++) + { + pThis->Lock(); + CComPtr punkConnection = m_vec.GetAt(iConnection); + pThis->Unlock(); + + IDispatch * pConnection = static_cast(punkConnection.p); + + if (pConnection) + { + CComVariant avarParams[2]; + avarParams[1] = test; + avarParams[1].vt = VT_I4; + avarParams[0] = testtest; + avarParams[0].vt = VT_BSTR; + CComVariant varResult; + + DISPPARAMS params = { avarParams, NULL, 2, 0 }; + hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL); + } + } + return hr; + }*/ }; diff --git a/pEpCOMServerAdapter.idl b/pEpCOMServerAdapter.idl index f757469..58030e1 100644 --- a/pEpCOMServerAdapter.idl +++ b/pEpCOMServerAdapter.idl @@ -302,7 +302,9 @@ library pEpCOMServerAdapterLib { properties: methods: - }; + // test code - remove before shipping + // [id(1)] HRESULT TestEvent([in] LONG test,[in] BSTR testtest); + }; [ uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2) ] From b7d0b6bc54c8686b3ee5e1e9359b8e4a46ba434e Mon Sep 17 00:00:00 2001 From: Edouard Tisserant Date: Mon, 20 Jun 2016 14:45:09 +0200 Subject: [PATCH 3/5] Ignore decrypt flags recently added to pEpEngine, so that adapters builds again --- CpEpEngine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index 514c9a4..acbe0da 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -1140,7 +1140,8 @@ STDMETHODIMP CpEpEngine::decrypt_message(text_message * src, text_message * dst, ::stringlist_t *_keylist; ::PEP_color _rating; - PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating); + // TODO : output decrypt flags. + PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, NULL); if (msg_dst) text_message_from_C(dst, msg_dst); From 59c326d99c09e8b462f05b8a186bc5ed30b0d0f3 Mon Sep 17 00:00:00 2001 From: Edouard Tisserant Date: Mon, 20 Jun 2016 15:01:00 +0200 Subject: [PATCH 4/5] Ignore decrypt flags recently added to pEpEngine, so that adapters builds again (again) --- CpEpEngine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index acbe0da..d0f4656 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -1140,8 +1140,9 @@ STDMETHODIMP CpEpEngine::decrypt_message(text_message * src, text_message * dst, ::stringlist_t *_keylist; ::PEP_color _rating; + PEP_decrypt_flags_t flags = 0; + PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, &flags); // TODO : output decrypt flags. - PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, NULL); if (msg_dst) text_message_from_C(dst, msg_dst); From 254eeceaa87a188b324006a0728c3d1801aa80f9 Mon Sep 17 00:00:00 2001 From: Edouard Tisserant Date: Mon, 20 Jun 2016 15:23:33 +0200 Subject: [PATCH 5/5] Ignore private keylist output of import_key recently added to pEpEngine, so that adapters builds again --- CpEpEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index d0f4656..a8a4bdf 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -625,7 +625,7 @@ STDMETHODIMP CpEpEngine::import_key(BSTR key_data) string _key_data = utf8_string(key_data); - PEP_STATUS status = ::import_key(get_session(), _key_data.c_str(), _key_data.length()); + PEP_STATUS status = ::import_key(get_session(), _key_data.c_str(), _key_data.length(), NULL); assert(status != PEP_OUT_OF_MEMORY); if (status == PEP_OUT_OF_MEMORY) return E_OUTOFMEMORY; @@ -643,7 +643,7 @@ STDMETHODIMP CpEpEngine::import_key_b(SAFEARRAY * key_data) if (key_data == NULL) return E_INVALIDARG; - ::PEP_STATUS status = ::import_key(get_session(), (const char *) key_data->pvData, key_data->rgsabound[0].cElements); + ::PEP_STATUS status = ::import_key(get_session(), (const char *) key_data->pvData, key_data->rgsabound[0].cElements, NULL); assert(status != ::PEP_OUT_OF_MEMORY); if (status == ::PEP_OUT_OF_MEMORY) return E_OUTOFMEMORY;