1 // CpEpEngine.h : Declaration of the CpEpEngine
4 #include "resource.h" // main symbols
6 #include "pEpComServerAdapter_i.h"
7 #include "locked_queue.hh"
8 #include "utf8_helper.h"
9 #include "pEp_utility.h"
13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
14 #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."
18 using namespace utility;
19 using namespace pEp::utility;
23 class ATL_NO_VTABLE CpEpEngine :
24 public CComObjectRootEx<CComObjectThreadModel>,
25 public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
26 public ISupportErrorInfo,
31 static int examine_identity(pEp_identity *ident, void *management);
34 CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
36 // See FinalConstruct() below for most initialization work, and an
37 // explanation why it had to be moved there...
43 StopKeyserverLookup();
44 if (m_session) // may be zero when FinalConstruct failed to initialize the engine
46 ::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
47 std::lock_guard<std::mutex> lock(init_mutex);
52 DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
54 DECLARE_NOT_AGGREGATABLE(CpEpEngine)
56 BEGIN_COM_MAP(CpEpEngine)
57 COM_INTERFACE_ENTRY(IpEpEngine)
58 COM_INTERFACE_ENTRY(ISupportErrorInfo)
62 STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
64 DECLARE_PROTECT_FINAL_CONSTRUCT()
66 // Unfortunately, neither FAIL nor error() work in the constructor, as
67 // CreateErrorInfo/SetErrorInfo cannot work when the instance is not constructed.
68 // AtlThrow works, but the exception is caught in CComCreator.CreateInstance, and
69 // unconditionally turned into E_OUTOFMEMORY. Thus, we need to do most constructor
70 // work in FinalConstruct. CreateErrorInfo/SetErrorInfo still won't work, but at least,
71 // we can return a meaningful HRESULT. Thus, we pack our PEP_STATUS into a custom HRESULT.
72 HRESULT FinalConstruct()
74 std::lock_guard<std::mutex> lock(init_mutex);
75 PEP_STATUS status = ::init(&m_session);
76 assert(status == PEP_STATUS_OK);
77 if (status != PEP_STATUS_OK) {
78 HRESULT res = MAKE_HRESULT(1, FACILITY_ITF, (0xFFFF & status));
82 ::register_examine_function(m_session, CpEpEngine::examine_identity, (void *)this);
83 ::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
99 session(CpEpEngine *myself)
102 me->session_mutex.lock();
107 me->session_mutex.unlock();
110 operator PEP_SESSION const ()
112 return me->m_session;
116 session get_session()
118 return session(this);
121 typedef locked_queue<pEp_identity_cpp> identity_queue_t;
122 static ::pEp_identity * retrieve_next_identity(void *management);
123 static PEP_STATUS messageToSend(void * obj, message *msg);
124 static PEP_STATUS notifyHandshake(void * obj, pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal);
127 HRESULT error(_bstr_t msg);
128 HRESULT error(_bstr_t msg, PEP_STATUS errorcode);
130 void verbose(string text)
134 ss << __FILE__ << ":" << __LINE__ << " " << text;
135 ::log_event(get_session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
140 PEP_SESSION m_session;
142 atomic< identity_queue_t * > identity_queue;
143 thread *keymanagement_thread;
147 IpEpEngineCallbacks* client_callbacks = NULL;
148 IpEpEngineCallbacks* client_callbacks_on_sync_thread = NULL;
149 bool client_last_signalled_polling_state = true;
152 static int inject_sync_msg(void *msg, void* management);
153 static void* retrieve_next_sync_msg(void* management, time_t *timeout);
154 void start_keysync();
155 static void do_keysync_in_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
158 static std::mutex init_mutex;
160 std::recursive_mutex keysync_mutex;
161 std::condition_variable_any keysync_condition;
162 std::thread *keysync_thread = NULL;
163 std::queue<void*> keysync_queue;
164 bool keysync_abort_requested = false;
165 PEP_SESSION keysync_session;
167 // Members used for handshake notification dispatch to the background thread.
168 static void notify_handshake_background_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
169 void notify_handshake_deliver_result();
170 bool notify_handshake_active = false;
171 bool notify_handshake_finished = false;
172 std::thread *notify_handshake_thread = NULL;
173 pEpIdentity notify_handshake_self;
174 pEpIdentity notify_handshake_partner;
175 SyncHandshakeSignal notify_handshake_signal;
176 SyncHandshakeResult notify_handshake_result;
177 LPSTREAM notify_handshake_error_info = NULL;
178 HRESULT notify_handshake_error;
181 // runtime config of the adapter
183 STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
185 // runtime config of the engine
187 STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
188 STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
192 STDMETHOD(ExportKey)(BSTR fpr, BSTR * keyData);
193 STDMETHOD(Log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
194 STDMETHOD(Trustwords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
195 STDMETHOD(GetTrustwords)(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words);
196 STDMETHOD(GetMessageTrustwords)(
197 /* [in] */ struct TextMessage *msg,
198 /* [in] */ struct pEpIdentity *receivedBy,
199 /* [in] */ SAFEARRAY *keylist,
200 /* [defaultvalue][in] */ BSTR lang,
201 /* [defaultvalue][in] */ VARIANT_BOOL full,
202 /* [retval][out] */ BSTR *words);
203 STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
204 STDMETHOD(GetEngineVersion)(BSTR * engineVersion);
205 STDMETHOD(GetLanguageList)(BSTR * languages);
206 STDMETHOD(SetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
207 STDMETHOD(UnsetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
211 STDMETHOD(StartKeyserverLookup)();
212 STDMETHOD(StopKeyserverLookup)();
214 STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
215 STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
216 STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
217 STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
218 STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
219 STDMETHOD(OwnIdentitiesRetrieve)(LPSAFEARRAY* ownIdentities);
221 STDMETHOD(UndoLastMistrust)();
223 STDMETHOD(IsPepUser)(
224 /* [in] */ struct pEpIdentity *ident,
225 /* [retval][out] */ VARIANT_BOOL *ispEp);
229 STDMETHOD(BlacklistAdd)(BSTR fpr);
230 STDMETHOD(BlacklistDelete)(BSTR fpr);
231 STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
232 STDMETHOD(BlacklistRetrieve)(SAFEARRAY **blacklist);
236 STDMETHOD(EncryptMessage)(
237 /* [in] */ struct TextMessage *src,
238 /* [out] */ struct TextMessage *dst,
239 /* [in] */ SAFEARRAY * extra,
240 /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
241 /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
243 STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
244 STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
245 STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
246 STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
247 STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
249 STDMETHOD(EncryptMessageForSelf)(
250 pEpIdentity * targetId,
253 pEpEncryptFlags flags
258 STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
259 STDMETHOD(UnregisterCallbacks)();
261 // PGP compatibility functions
262 STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
266 HRESULT Fire_MessageToSend(
267 /* [in] */ struct TextMessage *msg);
270 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)