CpEpEngine.h
author Markus Schaber <markus@pep-security.net>
Wed, 07 Feb 2018 19:42:45 +0100
branchCOM-74
changeset 272 0cd9b4cde17c
parent 271 92866cd8b0c4
child 273 30be98685afa
permissions -rw-r--r--
COM-74: Expose _PEP_enc_format to app for EncryptMessage

- Suppress exception in the now-common case of PEP_KEY_NOT_FOUND as requested by Thomas.
     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 IpEpEngine
    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(ISupportErrorInfo)
    60 END_COM_MAP()
    61 
    62 // ISupportsErrorInfo
    63     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    64 
    65 
    66     DECLARE_PROTECT_FINAL_CONSTRUCT()
    67 
    68     HRESULT FinalConstruct()
    69     {
    70         return S_OK;
    71     }
    72 
    73     void FinalRelease()
    74     {
    75     }
    76 
    77 
    78 protected:
    79     class session
    80     {
    81     private:
    82         CpEpEngine *me;
    83 
    84     public:
    85         session(CpEpEngine *myself)
    86         {
    87             me = myself;
    88             me->session_mutex.lock();
    89         }
    90 
    91         ~session()
    92         {
    93             me->session_mutex.unlock();
    94         }
    95 
    96         operator PEP_SESSION const ()
    97         {
    98             return me->m_session;
    99         }
   100     };
   101 
   102     session get_session()
   103     {
   104         return session(this);
   105     }
   106 
   107     typedef locked_queue<pEp_identity_cpp> identity_queue_t;
   108     static ::pEp_identity * retrieve_next_identity(void *management);
   109     static PEP_STATUS messageToSend(void * obj, message *msg);
   110     static PEP_STATUS notifyHandshake(void * obj, pEp_identity *self, pEp_identity *partner, sync_handshake_signal signal);
   111 
   112 
   113     HRESULT error(_bstr_t msg);
   114     HRESULT error(_bstr_t msg, PEP_STATUS errorcode);
   115 
   116     void verbose(string text)
   117     {
   118         if (verbose_mode) {
   119             stringstream ss;
   120             ss << __FILE__ << ":" << __LINE__ << " " << text;
   121             ::log_event(get_session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
   122         }
   123     }
   124 
   125 private:
   126     PEP_SESSION m_session;
   127     mutex session_mutex;
   128     atomic< identity_queue_t * > identity_queue;
   129     thread *keymanagement_thread;
   130     bool verbose_mode;
   131 
   132 
   133     IpEpEngineCallbacks* client_callbacks = NULL;
   134     IpEpEngineCallbacks* client_callbacks_on_sync_thread = NULL;
   135     bool client_last_signalled_polling_state = true;
   136 
   137     // Keysync members
   138     static int inject_sync_msg(void *msg, void* management);
   139     static void* retrieve_next_sync_msg(void* management, time_t *timeout);
   140     void start_keysync();
   141     static void do_keysync_in_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
   142     void stop_keysync();
   143 
   144     static std::mutex init_mutex;
   145 
   146     std::recursive_mutex keysync_mutex;
   147     std::condition_variable_any keysync_condition;
   148     std::thread *keysync_thread = NULL;
   149     std::queue<void*> keysync_queue;
   150     bool keysync_abort_requested = false;
   151     PEP_SESSION keysync_session;
   152 
   153     // Members used for handshake notification dispatch to the background thread.
   154     static void notify_handshake_background_thread(CpEpEngine* self, LPSTREAM marshaled_callbacks);
   155     void notify_handshake_deliver_result();
   156     bool notify_handshake_active = false;
   157     bool notify_handshake_finished = false;
   158     std::thread *notify_handshake_thread = NULL;
   159     pEpIdentity notify_handshake_self;
   160     pEpIdentity notify_handshake_partner;
   161     SyncHandshakeSignal notify_handshake_signal;
   162     SyncHandshakeResult notify_handshake_result;
   163     LPSTREAM notify_handshake_error_info = NULL;
   164     HRESULT notify_handshake_error;
   165 
   166 public:
   167     // runtime config of the adapter
   168 
   169     STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
   170 
   171     // runtime config of the engine
   172 
   173     STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
   174     STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
   175 
   176     // basic API
   177 
   178     STDMETHOD(ExportKey)(BSTR fpr, BSTR * keyData);
   179     STDMETHOD(Log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
   180     STDMETHOD(Trustwords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
   181     STDMETHOD(GetTrustwords)(struct pEpIdentity *id1, struct pEpIdentity *id2, BSTR lang, VARIANT_BOOL full, BSTR *words);
   182     STDMETHOD(GetMessageTrustwords)(
   183         /* [in] */ struct TextMessage *msg,
   184         /* [in] */ struct pEpIdentity *receivedBy,
   185         /* [in] */ SAFEARRAY *keylist,
   186         /* [defaultvalue][in] */ BSTR lang,
   187         /* [defaultvalue][in] */ VARIANT_BOOL full,
   188         /* [retval][out] */ BSTR *words);
   189     STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
   190     STDMETHOD(GetEngineVersion)(BSTR * engineVersion);
   191     STDMETHOD(GetLanguageList)(BSTR * languages);
   192     STDMETHOD(SetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   193     STDMETHOD(UnsetIdentityFlags)(struct pEpIdentity *identity, pEpIdentityFlags flags);
   194 
   195     // keymanagement API
   196 
   197     STDMETHOD(StartKeyserverLookup)();
   198     STDMETHOD(StopKeyserverLookup)();
   199 
   200     STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
   201     STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
   202     STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
   203     STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
   204     STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
   205     STDMETHOD(OwnIdentitiesRetrieve)(LPSAFEARRAY* ownIdentities);
   206 
   207     // Blacklist API
   208 
   209     STDMETHOD(BlacklistAdd)(BSTR fpr);
   210     STDMETHOD(BlacklistDelete)(BSTR fpr);
   211     STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
   212     STDMETHOD(BlacklistRetrieve)(SAFEARRAY **blacklist);
   213 
   214     // Message API
   215 
   216     STDMETHOD(EncryptMessage)(
   217         /* [in] */ struct TextMessage *src,
   218         /* [out] */ struct TextMessage *dst,
   219         /* [in] */ SAFEARRAY * extra,
   220         /* [defaultvalue][in] */ pEpEncryptFlags flags = pEpEncryptFlagDefault,
   221         /* [defaultvalue][in] */ pEpEncFormat encFormat = pEpEncPep);
   222 
   223     STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
   224     STDMETHOD(ReEvaluateMessageRating)(TextMessage * msg, SAFEARRAY * x_KeyList, pEpRating x_EncStatus, pEpRating *rating);
   225     STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
   226     STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
   227     STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
   228 
   229     STDMETHOD(EncryptMessageForSelf)(
   230         pEpIdentity * targetId, 
   231         TextMessage* src,
   232         TextMessage *dst,
   233         pEpEncryptFlags flags
   234         );
   235 
   236     // Event callbacks
   237 
   238     STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
   239     STDMETHOD(UnregisterCallbacks)();
   240 
   241     // PGP compatibility functions
   242     STDMETHOD(OpenPGPListKeyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
   243 
   244     STDMETHOD(UndoLastMistrust)();
   245 
   246 protected:
   247     HRESULT Fire_MessageToSend(
   248         /* [in] */ struct TextMessage *msg);
   249 };
   250 
   251 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)