CpEpEngine.h
author Volker Birk <vb@pep.foundation>
Sat, 24 Feb 2018 20:46:07 +0100
changeset 275 08f4040eca91
parent 264 aa6bd84bd6c3
child 277 6d26da1671b3
permissions -rw-r--r--
adding SetOwnKey
     1 // CpEpEngine.h : Declaration of the CpEpEngine
     2 
     3 #pragma once
     4 #include "resource.h"       // main symbols
     5 
     6 #include "pEpComServerAdapter_i.h"
     7 #include "locked_queue.hh"
     8 #include "utf8_helper.h"
     9 #include "pEp_utility.h"
    10 #include <queue>
    11 #include <mutex>
    12 
    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."
    15 #endif
    16 
    17 using namespace ATL;
    18 using namespace utility;
    19 using namespace pEp::utility;
    20 
    21 // CpEpEngine
    22 
    23 class ATL_NO_VTABLE CpEpEngine :
    24     public CComObjectRootEx<CComObjectThreadModel>,
    25 	public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
    26 	public ISupportErrorInfo,
    27 	public IpEpEngine2
    28 {
    29 
    30 protected:
    31     static int examine_identity(pEp_identity *ident, void *management);
    32 
    33 public:
    34     CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
    35 	{
    36 		std::lock_guard<std::mutex> lock(init_mutex);
    37 		PEP_STATUS status = ::init(&m_session);
    38 		assert(status == PEP_STATUS_OK);
    39 
    40         ::register_examine_function(m_session, CpEpEngine::examine_identity, (void *)this);
    41         ::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
    42     }
    43 
    44     ~CpEpEngine()
    45     {
    46         stop_keysync();
    47         StopKeyserverLookup();
    48         ::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
    49 		std::lock_guard<std::mutex> lock(init_mutex);
    50 		::release(m_session);
    51     }
    52 
    53 DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
    54 
    55 DECLARE_NOT_AGGREGATABLE(CpEpEngine)
    56 
    57 BEGIN_COM_MAP(CpEpEngine)
    58     COM_INTERFACE_ENTRY(IpEpEngine)
    59     COM_INTERFACE_ENTRY(IpEpEngine2)
    60     COM_INTERFACE_ENTRY(ISupportErrorInfo)
    61 END_COM_MAP()
    62 
    63 // ISupportsErrorInfo
    64 	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    65 
    66 
    67 	DECLARE_PROTECT_FINAL_CONSTRUCT()
    68 
    69 	HRESULT FinalConstruct()
    70 	{
    71 		return S_OK;
    72 	}
    73 
    74 	void FinalRelease()
    75 	{
    76 	}
    77 
    78 
    79 protected:
    80     class session
    81     {
    82     private:
    83         CpEpEngine *me;
    84 
    85     public:
    86         session(CpEpEngine *myself)
    87         {
    88             me = myself;
    89             me->session_mutex.lock();
    90         }
    91 
    92         ~session()
    93         {
    94             me->session_mutex.unlock();
    95         }
    96 
    97         operator PEP_SESSION const ()
    98         {
    99             return me->m_session;
   100         }
   101     };
   102 
   103     session get_session()
   104     {
   105         return session(this);
   106     }
   107 
   108     typedef locked_queue<pEp_identity_cpp> identity_queue_t;
   109     static ::pEp_identity * retrieve_next_identity(void *management);
   110     static PEP_STATUS messageToSend(void * obj, message *msg);
   111     static PEP_STATUS notifyHandshake(void * obj, pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal);
   112 
   113 
   114     HRESULT error(_bstr_t msg);
   115     HRESULT error(_bstr_t msg, PEP_STATUS errorcode);
   116 
   117     void verbose(string text)
   118     {
   119         if (verbose_mode) {
   120             stringstream ss;
   121             ss << __FILE__ << ":" << __LINE__ << " " << text;
   122             ::log_event(get_session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
   123         }
   124     }
   125 
   126 private:
   127     PEP_SESSION m_session;
   128     mutex session_mutex;
   129     atomic< identity_queue_t * > identity_queue;
   130     thread *keymanagement_thread;
   131     bool verbose_mode;
   132 
   133 
   134 	IpEpEngineCallbacks* client_callbacks = NULL;
   135     IpEpEngineCallbacks* client_callbacks_on_sync_thread = NULL;
   136     IpEpEngineCallbacks2* client_callbacks2_on_sync_thread = NULL;
   137     bool client_last_signalled_polling_state = true;
   138 
   139 	// Keysync members
   140     static int inject_sync_msg(void *msg, void* management);
   141     static void* retrieve_next_sync_msg(void* management, time_t *timeout);
   142     void start_keysync();
   143     static void do_keysync_in_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
   144     void stop_keysync();
   145 
   146 	static std::mutex init_mutex;
   147 
   148     std::recursive_mutex keysync_mutex;
   149     std::condition_variable_any keysync_condition;
   150     std::thread *keysync_thread = NULL;
   151     std::queue<void*> keysync_queue;
   152     bool keysync_abort_requested = false;
   153     PEP_SESSION keysync_session;
   154 
   155     // Members used for handshake notification dispatch to the background thread.
   156     static void notify_handshake_background_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
   157     void notify_handshake_deliver_result();
   158     bool notify_handshake_active = false;
   159     bool notify_handshake_finished = false;
   160     std::thread *notify_handshake_thread = NULL;
   161     pEpIdentity notify_handshake_self;
   162     pEpIdentity notify_handshake_partner;
   163     SyncHandshakeSignal notify_handshake_signal;
   164     SyncHandshakeResult notify_handshake_result;
   165     LPSTREAM notify_handshake_error_info = NULL;
   166     HRESULT notify_handshake_error;
   167 
   168 public:
   169     // runtime config of the adapter
   170 
   171     STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
   172 
   173     // runtime config of the engine
   174 
   175     STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
   176     STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
   177 
   178     // basic API
   179 
   180     STDMETHOD(ExportKey)(BSTR fpr, BSTR * keyData);
   181     STDMETHOD(Log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
   182     STDMETHOD(Trustwords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
   183     STDMETHOD(GetTrustwords)(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words);
   184     STDMETHOD(GetMessageTrustwords)(
   185         /* [in] */ struct TextMessage *msg,
   186         /* [in] */ struct pEpIdentity *receivedBy,
   187         /* [in] */ SAFEARRAY *keylist,
   188         /* [defaultvalue][in] */ BSTR lang,
   189         /* [defaultvalue][in] */ VARIANT_BOOL full,
   190         /* [retval][out] */ BSTR *words);
   191     STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
   192     STDMETHOD(GetEngineVersion)(BSTR * engineVersion);
   193     STDMETHOD(GetLanguageList)(BSTR * languages);
   194 	STDMETHOD(SetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   195 	STDMETHOD(UnsetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   196 
   197     // keymanagement API
   198 
   199     STDMETHOD(StartKeyserverLookup)();
   200     STDMETHOD(StopKeyserverLookup)();
   201 
   202     STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
   203     STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
   204     STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
   205     STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
   206     STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
   207 	STDMETHOD(OwnIdentitiesRetrieve)(LPSAFEARRAY* ownIdentities);
   208 
   209     // Blacklist API
   210 
   211     STDMETHOD(BlacklistAdd)(BSTR fpr);
   212     STDMETHOD(BlacklistDelete)(BSTR fpr);
   213     STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
   214     STDMETHOD(BlacklistRetrieve)(SAFEARRAY **blacklist);
   215 
   216     // Message API
   217 
   218     STDMETHOD(EncryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY * extra, pEpEncryptFlags flags);
   219     STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
   220     STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
   221     STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
   222     STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
   223 	STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
   224 
   225     STDMETHOD(EncryptMessageForSelf)(
   226         pEpIdentity * targetId, 
   227         TextMessage* src,
   228         TextMessage *dst,
   229         pEpEncryptFlags flags
   230         );
   231 
   232 	// Event callbacks
   233 
   234 	STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
   235 	STDMETHOD(UnregisterCallbacks)();
   236 
   237     // PGP compatibility functions
   238     STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
   239 
   240 	STDMETHOD(UndoLastMistrust)();
   241 	STDMETHOD(SetOwnKey)(pEpIdentity * ident, BSTR fpr, struct pEpIdentity *result);
   242 
   243 protected:
   244 	HRESULT Fire_MessageToSend(
   245 		/* [in] */ struct TextMessage *msg);
   246 };
   247 
   248 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)