Experimental implementation of events via explicit callback interface Experimental_Callback_Events
authorMarkus Schaber <markus@pep-security.net>
Thu, 26 May 2016 00:11:36 +0200
branchExperimental_Callback_Events
changeset 84ec2e6174b307
parent 83 9b7371990473
child 85 8939007c795b
Experimental implementation of events via explicit callback interface
CpEpEngine.cpp
CpEpEngine.h
_IpEpEngineEvents_CP.h
pEpCOMServerAdapter.idl
pEpCOMServerAdapter.vcxproj
pEpCOMServerAdapter.vcxproj.filters
pEpComAdapter.idl
     1.1 --- a/CpEpEngine.cpp	Wed May 25 13:04:50 2016 +0200
     1.2 +++ b/CpEpEngine.cpp	Thu May 26 00:11:36 2016 +0200
     1.3 @@ -811,6 +811,11 @@
     1.4      if (_ident == NULL)
     1.5          return E_OUTOFMEMORY;
     1.6  
     1.7 +	// DEBUG CODE - REMOVE BEFORE RELEASE!
     1.8 +	//sync_handshake_result_s handshakeResult;
     1.9 +	//
    1.10 +	//HRESULT res = Fire_ShowHandshake(ident, result, &handshakeResult);
    1.11 +
    1.12      PEP_STATUS status = ::myself(get_session(), _ident);
    1.13  
    1.14      if (status == PEP_STATUS_OK) {
    1.15 @@ -1244,3 +1249,66 @@
    1.16  
    1.17      return S_OK;
    1.18  }
    1.19 +
    1.20 +
    1.21 +// Event callbacks
    1.22 +
    1.23 +STDMETHODIMP CpEpEngine::register_callbacks(IpEpEngineCallbacks* new_callbacks) 
    1.24 +{
    1.25 +	callbacks cbs = get_callbacks();
    1.26 +	vector<IpEpEngineCallbacks*>& vec = cbs;
    1.27 +
    1.28 +	vec.push_back(new_callbacks);
    1.29 +	new_callbacks->AddRef();
    1.30 +
    1.31 +	return S_OK;
    1.32 +}
    1.33 +
    1.34 +STDMETHODIMP CpEpEngine::unregister_callbacks(IpEpEngineCallbacks* obsolete_callbacks) 
    1.35 +{
    1.36 +	callbacks cbs = get_callbacks();
    1.37 +	vector<IpEpEngineCallbacks*>& vec = cbs;
    1.38 +
    1.39 +	auto position = std::find(vec.begin(), vec.end(), obsolete_callbacks);
    1.40 +	if (position != vec.end()) {
    1.41 +		vec.erase(position);
    1.42 +		obsolete_callbacks->Release();
    1.43 +		return S_OK;
    1.44 +	}
    1.45 +
    1.46 +	return S_FALSE;
    1.47 +}
    1.48 +
    1.49 +HRESULT CpEpEngine::Fire_MessageToSend(text_message * msg)
    1.50 +{
    1.51 +	callbacks cbs = get_callbacks();
    1.52 +	vector<IpEpEngineCallbacks*>& vec = cbs;
    1.53 +
    1.54 +	assert(msg);
    1.55 +
    1.56 +	for (auto it = vec.begin(); it != vec.end(); ++it) 
    1.57 +	{
    1.58 +		auto res = (*it)->MessageToSend(msg);
    1.59 +		if (res != S_OK)
    1.60 +			return res;
    1.61 +	}
    1.62 +	return S_OK;
    1.63 +}
    1.64 +
    1.65 +HRESULT CpEpEngine::Fire_ShowHandshake(pEp_identity_s * self, pEp_identity_s * partner, sync_handshake_result_s * result)
    1.66 +{
    1.67 +	callbacks cbs = get_callbacks();
    1.68 +	vector<IpEpEngineCallbacks*>& vec = cbs;
    1.69 +
    1.70 +	assert(self);
    1.71 +	assert(partner);
    1.72 +	assert(result);
    1.73 +
    1.74 +	for (auto it = vec.begin(); it != vec.end(); ++it)
    1.75 +	{
    1.76 +		auto res = (*it)->ShowHandshake(self, partner, result);
    1.77 +		if (res != S_OK)
    1.78 +			return res;
    1.79 +	}
    1.80 +	return S_OK;
    1.81 +}
     2.1 --- a/CpEpEngine.h	Wed May 25 13:04:50 2016 +0200
     2.2 +++ b/CpEpEngine.h	Thu May 26 00:11:36 2016 +0200
     2.3 @@ -107,6 +107,34 @@
     2.4          return session(this);
     2.5      }
     2.6  
     2.7 +	class callbacks
     2.8 +	{
     2.9 +	private:
    2.10 +		CpEpEngine *me;
    2.11 +
    2.12 +	public:
    2.13 +		callbacks(CpEpEngine *myself)
    2.14 +		{
    2.15 +			me = myself;
    2.16 +			me->callback_mutex.lock();
    2.17 +		}
    2.18 +
    2.19 +		~callbacks()
    2.20 +		{
    2.21 +			me->callback_mutex.unlock();
    2.22 +		}
    2.23 +
    2.24 +		operator vector<IpEpEngineCallbacks *>& ()
    2.25 +		{
    2.26 +			return me->callback_vector;
    2.27 +		}
    2.28 +	};
    2.29 +
    2.30 +	callbacks get_callbacks()
    2.31 +	{
    2.32 +		return callbacks(this);
    2.33 +	}
    2.34 +
    2.35      typedef locked_queue<pEp_identity_cpp> identity_queue_t;
    2.36      static ::pEp_identity * retrieve_next_identity(void *management);
    2.37      static PEP_STATUS messageToSend(void *obj, const message *msg);
    2.38 @@ -130,6 +158,9 @@
    2.39      thread *keymanagement_thread;
    2.40      bool verbose_mode;
    2.41  
    2.42 +	mutex callback_mutex;
    2.43 +	vector<IpEpEngineCallbacks*> callback_vector;
    2.44 +
    2.45  public:
    2.46      // runtime config of the adapter
    2.47  
    2.48 @@ -190,6 +221,19 @@
    2.49      STDMETHOD(outgoing_message_color)(text_message *msg, pEp_color * pVal);
    2.50      STDMETHOD(identity_color)(pEp_identity_s * ident, pEp_color * pVal);
    2.51  
    2.52 +	// Event callbacks
    2.53 +
    2.54 +	STDMETHOD(register_callbacks)(IpEpEngineCallbacks *new_callback);
    2.55 +	STDMETHOD(unregister_callbacks)(IpEpEngineCallbacks *obsolete_callback);
    2.56 +
    2.57 +protected:
    2.58 +	HRESULT Fire_MessageToSend(
    2.59 +		/* [in] */ struct text_message *msg);
    2.60 +
    2.61 +	HRESULT Fire_ShowHandshake(
    2.62 +		/* [in] */ struct pEp_identity_s *self,
    2.63 +		/* [in] */ struct pEp_identity_s *partner,
    2.64 +		/* [retval][out] */ sync_handshake_result_s *result);
    2.65  };
    2.66  
    2.67  OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)
     3.1 --- a/_IpEpEngineEvents_CP.h	Wed May 25 13:04:50 2016 +0200
     3.2 +++ b/_IpEpEngineEvents_CP.h	Thu May 26 00:11:36 2016 +0200
     3.3 @@ -5,59 +5,5 @@
     3.4  	public ATL::IConnectionPointImpl<T, &__uuidof(_IpEpEngineEvents)>
     3.5  {
     3.6  public:
     3.7 -	HRESULT Fire_MessageToSend(text_message * msg)
     3.8 -	{
     3.9 -		HRESULT hr = S_OK;
    3.10 -		T * pThis = static_cast<T *>(this);
    3.11 -		int cConnections = m_vec.GetSize();
    3.12 -
    3.13 -		for (int iConnection = 0; iConnection < cConnections; iConnection++)
    3.14 -		{
    3.15 -			pThis->Lock();
    3.16 -			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
    3.17 -			pThis->Unlock();
    3.18 -
    3.19 -			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
    3.20 -
    3.21 -			if (pConnection)
    3.22 -			{
    3.23 -				CComVariant avarParams[1];
    3.24 -				avarParams[0] = msg;
    3.25 -				CComVariant varResult;
    3.26 -
    3.27 -				DISPPARAMS params = { avarParams, NULL, 1, 0 };
    3.28 -				hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
    3.29 -			}
    3.30 -		}
    3.31 -		return hr;
    3.32 -	}
    3.33 -	HRESULT Fire_ShowHandshake(pEp_identity_s * self, pEp_identity_s * partner, sync_handshake_result_s * result)
    3.34 -	{
    3.35 -		HRESULT hr = S_OK;
    3.36 -		T * pThis = static_cast<T *>(this);
    3.37 -		int cConnections = m_vec.GetSize();
    3.38 -
    3.39 -		for (int iConnection = 0; iConnection < cConnections; iConnection++)
    3.40 -		{
    3.41 -			pThis->Lock();
    3.42 -			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
    3.43 -			pThis->Unlock();
    3.44 -
    3.45 -			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
    3.46 -
    3.47 -			if (pConnection)
    3.48 -			{
    3.49 -				CComVariant avarParams[3];
    3.50 -				avarParams[2] = self;
    3.51 -				avarParams[1] = partner;
    3.52 -				avarParams[0] = result;
    3.53 -				CComVariant varResult;
    3.54 -
    3.55 -				DISPPARAMS params = { avarParams, NULL, 3, 0 };
    3.56 -				hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
    3.57 -			}
    3.58 -		}
    3.59 -		return hr;
    3.60 -	}
    3.61  };
    3.62  
     4.1 --- a/pEpCOMServerAdapter.idl	Wed May 25 13:04:50 2016 +0200
     4.2 +++ b/pEpCOMServerAdapter.idl	Thu May 26 00:11:36 2016 +0200
     4.3 @@ -7,6 +7,26 @@
     4.4  import "oaidl.idl";
     4.5  import "ocidl.idl";
     4.6  
     4.7 +
     4.8 +typedef enum _sync_handshake_result_s {
     4.9 +	SYNC_HANDSHAKE_CANCEL_S = -1,
    4.10 +	SYNC_HANDSHAKE_ACCEPTED_S = 0,
    4.11 +	SYNC_HANDSHAKE_REJECTED_S = 1
    4.12 +} sync_handshake_result_s;
    4.13 +
    4.14 +[
    4.15 +	object,
    4.16 +	uuid(3BA1B15B-27EF-433C-B780-0D08F46B0FF3),
    4.17 +	oleautomation,
    4.18 +	nonextensible,
    4.19 +	pointer_default(unique)
    4.20 +]
    4.21 +interface IpEpEngineCallbacks : IUnknown {
    4.22 +	[id(1)] HRESULT MessageToSend([in] struct text_message * msg);
    4.23 +	[id(2)] HRESULT ShowHandshake([in] struct pEp_identity_s * self, [in] struct pEp_identity_s * partner, [out, retval] sync_handshake_result_s * result);
    4.24 +};
    4.25 +
    4.26 +
    4.27  [
    4.28      object,
    4.29      uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540),
    4.30 @@ -262,11 +282,10 @@
    4.31      HRESULT outgoing_message_color([in] struct text_message *msg, [out, retval] pEp_color * pVal);
    4.32      HRESULT identity_color([in] struct pEp_identity_s * ident, [out, retval] pEp_color * pVal);
    4.33  
    4.34 -    typedef enum _sync_handshake_result_s {
    4.35 -        SYNC_HANDSHAKE_CANCEL_S = -1,
    4.36 -        SYNC_HANDSHAKE_ACCEPTED_S = 0,
    4.37 -        SYNC_HANDSHAKE_REJECTED_S = 1
    4.38 -    } sync_handshake_result_s;
    4.39 +
    4.40 +	HRESULT register_callbacks([in] IpEpEngineCallbacks* new_callback);
    4.41 +
    4.42 +	HRESULT unregister_callbacks([in] IpEpEngineCallbacks* obsolete_callback);
    4.43  };
    4.44  
    4.45  [
    4.46 @@ -283,8 +302,6 @@
    4.47      {
    4.48      properties:
    4.49      methods:
    4.50 -        [id(1)] HRESULT MessageToSend([in] struct text_message * msg);
    4.51 -        [id(2)] HRESULT ShowHandshake([in] struct pEp_identity_s * self, [in] struct pEp_identity_s * partner, [in,out] sync_handshake_result_s * result);
    4.52      };
    4.53      [
    4.54          uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2)
     5.1 --- a/pEpCOMServerAdapter.vcxproj	Wed May 25 13:04:50 2016 +0200
     5.2 +++ b/pEpCOMServerAdapter.vcxproj	Thu May 26 00:11:36 2016 +0200
     5.3 @@ -159,7 +159,7 @@
     5.4      <ClInclude Include="targetver.h" />
     5.5      <ClInclude Include="utf8_helper.h" />
     5.6      <ClInclude Include="xdlldata.h" />
     5.7 -    <ClInclude Include="_IpEpEngineEvents_CP.H" />
     5.8 +    <ClInclude Include="_IpEpEngineEvents_CP.h" />
     5.9    </ItemGroup>
    5.10    <ItemGroup>
    5.11      <ResourceCompile Include="pEpCOMServerAdapter.rc" />
     6.1 --- a/pEpCOMServerAdapter.vcxproj.filters	Wed May 25 13:04:50 2016 +0200
     6.2 +++ b/pEpCOMServerAdapter.vcxproj.filters	Thu May 26 00:11:36 2016 +0200
     6.3 @@ -69,7 +69,7 @@
     6.4      <ClInclude Include="pEp_utility.h">
     6.5        <Filter>Header Files</Filter>
     6.6      </ClInclude>
     6.7 -    <ClInclude Include="_IpEpEngineEvents_CP.H">
     6.8 +    <ClInclude Include="_IpEpEngineEvents_CP.h">
     6.9        <Filter>Generated Files</Filter>
    6.10      </ClInclude>
    6.11    </ItemGroup>
     7.1 --- a/pEpComAdapter.idl	Wed May 25 13:04:50 2016 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,145 +0,0 @@
     7.4 -// pEpComAdapter.idl : IDL source for pEpComAdapter
     7.5 -//
     7.6 -
     7.7 -// This file will be processed by the MIDL tool to
     7.8 -// produce the type library (pEpComAdapter.tlb) and marshalling code.
     7.9 -
    7.10 -import "oaidl.idl";
    7.11 -import "ocidl.idl";
    7.12 -
    7.13 -[
    7.14 -	object,
    7.15 -	uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540),
    7.16 -	oleautomation,
    7.17 -	nonextensible,
    7.18 -	pointer_default(unique)
    7.19 -]
    7.20 -interface IpEpEngine : IUnknown{
    7.21 -    typedef enum _pEp_STATUS {
    7.22 -        pEp_STATUS_OK = 0,
    7.23 -
    7.24 -        pEp_KEY_NOT_FOUND = 0x0201,
    7.25 -        pEp_KEY_HAS_AMBIG_NAME = 0x0202,
    7.26 -        pEp_GET_KEY_FAILED = 0x0203,
    7.27 -
    7.28 -        pEp_UNENCRYPTED = 0x0400,
    7.29 -        pEp_VERIFIED = 0x0401,
    7.30 -        pEp_DECRYPTED = 0x0402,
    7.31 -        pEp_DECRYPTED_AND_VERIFIED = 0x0403,
    7.32 -        pEp_DECRYPT_WRONG_FORMAT = 0x0404,
    7.33 -        pEp_DECRYPT_NO_KEY = 0x0405,
    7.34 -        pEp_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406,
    7.35 -        pEp_VERIFY_NO_KEY = 0x0407,
    7.36 -        pEp_VERIFIED_AND_TRUSTED = 0x0408,
    7.37 -
    7.38 -        pEp_ILLEGAL_VALUE = -4,
    7.39 -        pEp_BUFFER_TOO_SMALL = -3,
    7.40 -        pEp_OUT_OF_MEMORY = -2,
    7.41 -        pEp_UNKNOWN_ERROR = -1
    7.42 -    } pEp_STATUS;
    7.43 -
    7.44 -    [id(1)] HRESULT log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment);
    7.45 -    [id(2)] HRESULT decrypt([in] BSTR ctext, [out] BSTR * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
    7.46 -    [id(3)] HRESULT decrypt_b([in] BSTR ctext, [out] SAFEARRAY(BYTE) * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
    7.47 -    [id(4)] HRESULT encrypt([in] SAFEARRAY(BSTR) key_list, [in] BSTR ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
    7.48 -    [id(5)] HRESULT encrypt_b([in] SAFEARRAY(BSTR) key_list, [in] SAFEARRAY(BYTE) ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
    7.49 -    [id(21)] HRESULT verify([in] BSTR text, [in] BSTR signature, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * verify_status);
    7.50 -    [id(6)] HRESULT safeword([in] LONG value, [in, defaultvalue("en")] BSTR lang, [out, retval] BSTR * word);
    7.51 -    [id(7)] HRESULT safewords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG max_words, [out, retval] BSTR * words);
    7.52 -
    7.53 -    typedef enum _pEp_comm_type {
    7.54 -        pEp_ct_unknown = 0,
    7.55 -
    7.56 -        // range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable
    7.57 -
    7.58 -        pEp_ct_no_encryption = 0x01,                // generic
    7.59 -        pEp_ct_no_encrypted_channel = 0x02,
    7.60 -        pEp_ct_key_not_found = 0x03,
    7.61 -        pEp_ct_key_expired = 0x04,
    7.62 -        pEp_ct_key_revoked = 0x05,
    7.63 -        pEp_ct_key_b0rken = 0x06,
    7.64 -        pEp_ct_my_key_not_included = 0x09,
    7.65 -
    7.66 -        pEp_ct_security_by_obscurity = 0x0a,
    7.67 -        pEp_ct_b0rken_crypto = 0x0b,
    7.68 -        pEp_ct_key_too_short = 0x0e,
    7.69 -
    7.70 -        pEp_ct_compromized = 0x0f,                  // known compromized connection
    7.71 -
    7.72 -        // range 0x10 to 0x3f: unconfirmed encryption
    7.73 -
    7.74 -        pEp_ct_unconfirmed_encryption = 0x10,       // generic
    7.75 -        pEp_ct_OpenPGP_1024_RSA_unconfirmed = 0x11,	// RSA 1024 is weak
    7.76 -        pEp_ct_OpenPGP_unconfirmed = 0x3f,          // key at least 2048 bit RSA
    7.77 -        // or 1024 bit DSA
    7.78 -
    7.79 -        // range 0x40 to 0x7f: unconfirmed encryption and anonymization
    7.80 -
    7.81 -        pEp_ct_unconfirmed_enc_anon = 0x40,         // generic
    7.82 -        pEp_ct_pEp_unconfirmed = 0x7f,
    7.83 -
    7.84 -        pEp_ct_confirmed = 0x80,                    // this bit decides if trust is confirmed
    7.85 -
    7.86 -        // range 0x81 to 0x8f: reserved
    7.87 -        // range 0x90 to 0xbf: confirmed encryption
    7.88 -
    7.89 -        pEp_ct_confirmed_encryption = 0x90,         // generic
    7.90 -        pEp_ct_OpenPGP_1024_RSA = 0x91, // RSA 1024 is weak
    7.91 -        pEp_ct_OpenPGP = 0xbf, // key at least 2048 bit RSA or 1024 bit DSA
    7.92 -
    7.93 -        // range 0xc0 to 0xff: confirmed encryption and anonymization
    7.94 -
    7.95 -        pEp_ct_confirmed_enc_anon = 0xc0,           // generic
    7.96 -        pEp_ct_pEp = 0xff
    7.97 -    } pEp_comm_type;
    7.98 -
    7.99 -    struct pEp_identity_s {
   7.100 -        BSTR address;
   7.101 -        BSTR fpr;
   7.102 -        BSTR user_id;
   7.103 -        BSTR username;
   7.104 -        pEp_comm_type comm_type;
   7.105 -        BSTR lang;
   7.106 -    };
   7.107 -
   7.108 -    [id(8)] HRESULT get_identity([in] BSTR address, [out, retval] struct pEp_identity_s * ident);
   7.109 -    [id(9)] HRESULT set_identity([in] struct pEp_identity_s * ident);
   7.110 -    [id(10)] HRESULT generate_keypair([in] struct pEp_identity_s * ident, [out, retval] BSTR * fpr);
   7.111 -    [id(11)] HRESULT delete_keypair([in] BSTR fpr);
   7.112 -    [id(12)] HRESULT import_key([in] BSTR key_data);
   7.113 -    [id(13)] HRESULT import_key_b([in] SAFEARRAY(BYTE) key_data);
   7.114 -    [id(14)] HRESULT export_key([in] BSTR fpr, [out, retval] BSTR * key_data);
   7.115 -    [id(15)] HRESULT recv_key([in] BSTR pattern);
   7.116 -    [id(16)] HRESULT find_keys([in] BSTR pattern, [out, retval] SAFEARRAY(BSTR) * key_list);
   7.117 -    [id(17)] HRESULT send_key([in] BSTR pattern);
   7.118 -
   7.119 -    [id(19)] HRESULT examine_identity([in] struct pEp_identity_s * ident);
   7.120 -    [id(20)] HRESULT examine_myself([in] struct pEp_identity_s * myself);
   7.121 -    [id(22)] HRESULT myself([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
   7.122 -    [id(23)] HRESULT update_identity([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
   7.123 -};
   7.124 -[
   7.125 -	uuid(3EC2E1A4-40E8-48E4-A7B0-1876D34F9462),
   7.126 -	version(1.0),
   7.127 -]
   7.128 -library pEpComAdapterLib
   7.129 -{
   7.130 -	importlib("stdole2.tlb");
   7.131 -	[
   7.132 -		uuid(B6BC9B8E-D9E2-4419-A3A4-7B4B58175549)		
   7.133 -	]
   7.134 -	dispinterface _IpEpEngineEvents
   7.135 -	{
   7.136 -		properties:
   7.137 -		methods:
   7.138 -	};
   7.139 -	[
   7.140 -		uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2)		
   7.141 -	]
   7.142 -	coclass pEpEngine
   7.143 -	{
   7.144 -		[default] interface IpEpEngine;
   7.145 -		[default, source] dispinterface _IpEpEngineEvents;
   7.146 -	};
   7.147 -};
   7.148 -