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