p≡p COM server adapter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
10 KiB

8 years ago
4 years ago
8 years ago
4 years ago
4 years ago
4 years ago
8 years ago
4 years ago
8 years ago
8 years ago
8 years ago
7 years ago
8 years ago
4 years ago
4 years ago
4 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
4 years ago
4 years ago
4 years ago
8 years ago
8 years ago
8 years ago
4 years ago
4 years ago
8 years ago
8 years ago
7 years ago
4 years ago
7 years ago
8 years ago
4 years ago
4 years ago
8 years ago
7 years ago
8 years ago
8 years ago
7 years ago
3 years ago
4 years ago
4 years ago
5 years ago
8 years ago
  1. // CpEpEngine.h : Declaration of the CpEpEngine
  2. #pragma once
  3. #include "resource.h" // main symbols
  4. #include "pEpComServerAdapter_i.h"
  5. #include "..\libpEpAdapter\locked_queue.hh"
  6. #include "utf8_helper.h"
  7. #include "pEp_utility.h"
  8. #include "..\libpEpAdapter\Adapter.hh"
  9. #include <queue>
  10. #include <mutex>
  11. #include <vector>
  12. #include "..\libpEpAdapter\pc_container.hh"
  13. #include "..\pEp\sync_codec.h"
  14. #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
  15. #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
  16. #endif
  17. using namespace ATL;
  18. using namespace utility;
  19. using namespace pEp::utility;
  20. using namespace pEp::Adapter;
  21. // CpEpEngine
  22. class ATL_NO_VTABLE CpEpEngine :
  23. public CComObjectRootEx<CComObjectThreadModel>,
  24. public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
  25. public ISupportErrorInfo,
  26. public IpEpEngine
  27. {
  28. protected:
  29. static int examine_identity(pEp_identity *ident, void *management);
  30. public:
  31. CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
  32. {
  33. // See FinalConstruct() below for most initialization work, and an
  34. // explanation why it had to be moved there...
  35. ++count;
  36. }
  37. ~CpEpEngine()
  38. {
  39. --count;
  40. if (!count) {
  41. StopKeyserverLookup();
  42. ::log_event(session(), "Shutdown", "pEp COM Adapter", NULL, NULL);
  43. session(pEp::Adapter::release);
  44. shutdown();
  45. sync_callbacks.clear([](CpEpEngine::MarshaledCallbacks *p) {
  46. if (p) {
  47. if (p->marshaled)
  48. p->marshaled->Release();
  49. if (p->unmarshaled)
  50. p->unmarshaled->Release();
  51. delete p;
  52. }
  53. });
  54. }
  55. }
  56. DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
  57. DECLARE_NOT_AGGREGATABLE(CpEpEngine)
  58. BEGIN_COM_MAP(CpEpEngine)
  59. COM_INTERFACE_ENTRY(IpEpEngine)
  60. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  61. END_COM_MAP()
  62. // ISupportsErrorInfo
  63. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  64. DECLARE_PROTECT_FINAL_CONSTRUCT()
  65. // Unfortunately, neither FAIL nor error() work in the constructor, as
  66. // CreateErrorInfo/SetErrorInfo cannot work when the instance is not constructed.
  67. // AtlThrow works, but the exception is caught in CComCreator.CreateInstance, and
  68. // unconditionally turned into E_OUTOFMEMORY. Thus, we need to do most constructor
  69. // work in FinalConstruct. CreateErrorInfo/SetErrorInfo still won't work, but at least,
  70. // we can return a meaningful HRESULT. Thus, we pack our PEP_STATUS into a custom HRESULT.
  71. HRESULT FinalConstruct()
  72. {
  73. std::lock_guard<std::mutex> lock(init_mutex);
  74. try {
  75. session();
  76. }
  77. catch (pEp::RuntimeError& e) {
  78. HRESULT res = MAKE_HRESULT(1, FACILITY_ITF, (0xFFFF & e.status));
  79. return res;
  80. }
  81. ::register_examine_function(session(), CpEpEngine::examine_identity, (void *)this);
  82. ::log_event(session(), "FinalConstruct", "pEp COM Adapter", NULL, NULL);
  83. return S_OK;
  84. }
  85. void FinalRelease()
  86. {
  87. }
  88. struct MarshaledCallbacks {
  89. IpEpEngineCallbacks *unmarshaled;
  90. LPSTREAM marshaled;
  91. };
  92. typedef pEp::pc_container< MarshaledCallbacks, IpEpEngineCallbacks > callback_container;
  93. protected:
  94. typedef locked_queue<pEp_identity_cpp> identity_queue_t;
  95. static ::pEp_identity * retrieve_next_identity(void *management);
  96. static PEP_STATUS messageToSend(message *msg);
  97. static PEP_STATUS notifyHandshake(pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal);
  98. HRESULT error(_bstr_t msg);
  99. HRESULT error(_bstr_t msg, PEP_STATUS errorcode);
  100. void verbose(string text)
  101. {
  102. if (verbose_mode) {
  103. stringstream ss;
  104. ss << __FILE__ << ":" << __LINE__ << " " << text;
  105. ::log_event(session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
  106. }
  107. }
  108. private:
  109. // callbacks for sync
  110. static callback_container sync_callbacks;
  111. void Startup_sync()
  112. {
  113. HRESULT r = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  114. if (!SUCCEEDED(r))
  115. throw runtime_error("CoInitializeEx() failed on sync thread");
  116. }
  117. void Shutdown_sync()
  118. {
  119. for (auto p = sync_callbacks.begin(); p != sync_callbacks.end(); ++p) {
  120. if (p->cdata) {
  121. p->cdata->Release();
  122. p->cdata = nullptr;
  123. }
  124. }
  125. CoUninitialize();
  126. }
  127. atomic< identity_queue_t * > identity_queue;
  128. thread *keymanagement_thread;
  129. bool verbose_mode;
  130. IpEpEngineCallbacks* client_callbacks = NULL;
  131. bool client_last_signalled_polling_state = true;
  132. static std::mutex init_mutex;
  133. static atomic< int > count;
  134. public:
  135. // runtime config of the adapter
  136. STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
  137. // runtime config of the engine
  138. STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
  139. STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
  140. // basic API
  141. STDMETHOD(ExportKey)(BSTR fpr, BSTR * keyData);
  142. STDMETHOD(Log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
  143. STDMETHOD(Trustwords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
  144. STDMETHOD(GetTrustwords)(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words);
  145. STDMETHOD(GetTrustwordsForFprs)(BSTR fpr1, BSTR fpr2, BSTR lang, VARIANT_BOOL full, BSTR *words);
  146. STDMETHOD(GetMessageTrustwords)(
  147. /* [in] */ struct TextMessage *msg,
  148. /* [in] */ struct pEpIdentity *receivedBy,
  149. /* [in] */ SAFEARRAY *keylist,
  150. /* [defaultvalue][in] */ BSTR lang,
  151. /* [defaultvalue][in] */ VARIANT_BOOL full,
  152. /* [retval][out] */ BSTR *words);
  153. STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
  154. STDMETHOD(GetEngineVersion)(BSTR * engineVersion);
  155. STDMETHOD(GetLanguageList)(BSTR * languages);
  156. STDMETHOD(SetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
  157. STDMETHOD(UnsetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
  158. STDMETHOD(ImportKey)(BSTR keyData, LPSAFEARRAY *privateKeys);
  159. // keymanagement API
  160. STDMETHOD(StartKeyserverLookup)();
  161. STDMETHOD(StopKeyserverLookup)();
  162. STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
  163. STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
  164. STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
  165. STDMETHOD(KeyResetIdentity)(pEpIdentity ident, BSTR fpr);
  166. STDMETHOD(KeyResetUser)(BSTR userId, BSTR fpr);
  167. STDMETHOD(KeyResetAllOwnKeys)();
  168. STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
  169. STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
  170. STDMETHOD(OwnIdentitiesRetrieve)(LPSAFEARRAY* ownIdentities);
  171. STDMETHOD(ConfigCipherSuite)(pEpCipherSuite cipherSuite);
  172. // STDMETHOD(UndoLastMistrust)();
  173. STDMETHOD(IspEpUser)(
  174. /* [in] */ struct pEpIdentity *ident,
  175. /* [retval][out] */ VARIANT_BOOL *ispEp);
  176. // Blacklist API
  177. STDMETHOD(BlacklistAdd)(BSTR fpr);
  178. STDMETHOD(BlacklistDelete)(BSTR fpr);
  179. STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
  180. STDMETHOD(BlacklistRetrieve)(SAFEARRAY **blacklist);
  181. // Message API
  182. STDMETHOD(EncryptMessage)(
  183. /* [in] */ struct TextMessage *src,
  184. /* [out] */ struct TextMessage *dst,
  185. /* [in] */ SAFEARRAY * extra,
  186. /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
  187. /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
  188. STDMETHOD(EncryptMessageAndAddPrivKey)(
  189. /* [in] */ struct TextMessage *src,
  190. /* [out] */ struct TextMessage *dst,
  191. /* [in] */ BSTR to_fpr,
  192. /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
  193. /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
  194. STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
  195. STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
  196. STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
  197. STDMETHOD(OutgoingMessageRatingPreview)(TextMessage *msg, pEpRating * pVal);
  198. STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
  199. STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
  200. STDMETHOD(EncryptMessageForSelf)(
  201. pEpIdentity * targetId,
  202. TextMessage* src,
  203. /* [in] */ SAFEARRAY *extra,
  204. TextMessage *dst,
  205. pEpEncryptFlags flags
  206. );
  207. // Event callbacks
  208. STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
  209. STDMETHOD(UnregisterCallbacks)();
  210. // PGP compatibility functions
  211. STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
  212. STDMETHOD(SetOwnKey)(pEpIdentity * ident, BSTR fpr, struct pEpIdentity *result);
  213. STDMETHOD(TrustOwnKey)(pEpIdentity * ident);
  214. // Trigger an immediate update
  215. STDMETHOD(UpdateNow)();
  216. STDMETHOD(Startup)();
  217. STDMETHOD(GetKeyRatingForUser)(BSTR userId, BSTR fpr, pEpRating *rating);
  218. STDMETHOD(GetKeyRating)(BSTR fpr, pEpComType *commType);
  219. // sync API
  220. STDMETHOD(DeliverHandshakeResult)(enum SyncHandshakeResult result, SAFEARRAY *identities_sharing);
  221. STDMETHOD(LeaveDeviceGroup)();
  222. STDMETHOD(PERToXERSyncMessage)(TextMessage *msg, BSTR * xer);
  223. };
  224. OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)