CpEpEngine.h
author Markus Schaber <markus@pep-security.net>
Tue, 04 Oct 2016 21:50:26 +0200
branchkeysync
changeset 175 9aabb2c9df08
parent 172 112b0fac353d
child 177 4d197f1c3abb
permissions -rw-r--r--
COM-29: Adapt to new interface changes in the engine.
     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 // TODO: Remove this enum, it is not needed in the interface, but it currently is still used in the code which is
    22 // not removed / reworked yet...
    23 typedef enum pEpStatus {
    24      pEpStatusOK = 0,
    25 
    26      pEp_INIT_CANNOT_LOAD_GPGME = 0x0110,
    27      pEp_INIT_GPGME_INIT_FAILED = 0x0111,
    28      pEp_INIT_NO_GPG_HOME = 0x0112,
    29      pEp_INIT_NETPGP_INIT_FAILED = 0x0113,
    30 
    31      pEp_INIT_SQLITE3_WITHOUT_MUTEX = 0x0120,
    32      pEp_INIT_CANNOT_OPEN_DB = 0x0121,
    33      pEp_INIT_CANNOT_OPEN_SYSTEM_DB = 0x0122,
    34 
    35      pEp_KEY_NOT_FOUND = 0x0201,
    36      pEp_KEY_HAS_AMBIG_NAME = 0x0202,
    37      pEp_GET_KEY_FAILED = 0x0203,
    38 
    39      pEp_CANNOT_FIND_IDENTITY = 0x0301,
    40      pEp_CANNOT_SET_PERSON = 0x0381,
    41      pEp_CANNOT_SET_PGP_KEYPAIR = 0x0382,
    42      pEp_CANNOT_SET_IDENTITY = 0x0383,
    43      pEp_CANNOT_SET_TRUST = 0x0384,
    44 
    45      pEp_UNENCRYPTED = 0x0400,
    46      pEp_VERIFIED = 0x0401,
    47      pEp_DECRYPTED = 0x0402,
    48      pEp_DECRYPTED_AND_VERIFIED = 0x0403,
    49      pEp_DECRYPT_WRONG_FORMAT = 0x0404,
    50      pEp_DECRYPT_NO_KEY = 0x0405,
    51      pEp_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406,
    52      pEp_VERIFY_NO_KEY = 0x0407,
    53      pEp_VERIFIED_AND_TRUSTED = 0x0408,
    54      pEp_CANNOT_DECRYPT_UNKNOWN = 0x04ff,
    55 
    56      pEp_TRUSTWORD_NOT_FOUND = 0x0501,
    57 
    58      pEp_CANNOT_CREATE_KEY = 0x0601,
    59      pEp_CANNOT_SEND_KEY = 0x0602,
    60 
    61      pEp_PHRASE_NOT_FOUND = 0x0701,
    62 
    63      pEp_COMMIT_FAILED = 0xff01,
    64 
    65      pEp_CANNOT_CREATE_TEMP_FILE = -5,
    66      pEp_ILLEGAL_VALUE = -4,
    67      pEp_BUFFER_TOO_SMALL = -3,
    68      pEp_OUT_OF_MEMORY = -2,
    69      pEp_UNKNOWN_ERROR = -1
    70  } pEpStatus;
    71 
    72 // CpEpEngine
    73 
    74 class ATL_NO_VTABLE CpEpEngine :
    75     public CComObjectRootEx<CComObjectThreadModel>,
    76 	public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
    77 	public ISupportErrorInfo,
    78 	public IpEpEngine
    79 {
    80 protected:
    81     static int examine_identity(pEp_identity *ident, void *management);
    82 
    83 public:
    84     CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
    85 	{
    86         PEP_STATUS status = ::init(&m_session);
    87         assert(status == PEP_STATUS_OK);
    88         ::register_examine_function(m_session, CpEpEngine::examine_identity, (void *)this);
    89         ::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
    90     }
    91 
    92     ~CpEpEngine()
    93     {
    94         stop_keysync();
    95         StopKeyserverLookup();
    96         ::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
    97         ::release(m_session);
    98     }
    99 
   100 DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
   101 
   102 DECLARE_NOT_AGGREGATABLE(CpEpEngine)
   103 
   104 BEGIN_COM_MAP(CpEpEngine)
   105     COM_INTERFACE_ENTRY(IpEpEngine)
   106     COM_INTERFACE_ENTRY(ISupportErrorInfo)
   107 END_COM_MAP()
   108 
   109 // ISupportsErrorInfo
   110 	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
   111 
   112 
   113 	DECLARE_PROTECT_FINAL_CONSTRUCT()
   114 
   115 	HRESULT FinalConstruct()
   116 	{
   117 		return S_OK;
   118 	}
   119 
   120 	void FinalRelease()
   121 	{
   122 	}
   123 
   124 
   125 protected:
   126     class session
   127     {
   128     private:
   129         CpEpEngine *me;
   130 
   131     public:
   132         session(CpEpEngine *myself)
   133         {
   134             me = myself;
   135             me->session_mutex.lock();
   136         }
   137 
   138         ~session()
   139         {
   140             me->session_mutex.unlock();
   141         }
   142 
   143         operator PEP_SESSION const ()
   144         {
   145             return me->m_session;
   146         }
   147     };
   148 
   149     session get_session()
   150     {
   151         return session(this);
   152     }
   153 
   154 	class callbacks
   155 	{
   156 	private:
   157 		CpEpEngine *me;
   158 
   159 	public:
   160 		callbacks(CpEpEngine *myself)
   161 		{
   162 			me = myself;
   163 			me->callback_mutex.lock();
   164 		}
   165 
   166 		~callbacks()
   167 		{
   168 			me->callback_mutex.unlock();
   169 		}
   170 
   171 		operator vector<IpEpEngineCallbacks *>& ()
   172 		{
   173 			return me->callback_vector;
   174 		}
   175 	};
   176 
   177 	callbacks get_callbacks()
   178 	{
   179 		return callbacks(this);
   180 	}
   181 
   182     typedef locked_queue<pEp_identity_cpp> identity_queue_t;
   183     static ::pEp_identity * retrieve_next_identity(void *management);
   184     static PEP_STATUS messageToSend(void * obj, message *msg);
   185     static PEP_STATUS showHandshake(void * obj, pEp_identity *self, pEp_identity *partner);
   186 
   187 
   188     HRESULT error(_bstr_t msg);
   189 
   190     void verbose(string text)
   191     {
   192         if (verbose_mode) {
   193             stringstream ss;
   194             ss << __FILE__ << ":" << __LINE__ << " " << text;
   195             ::log_event(get_session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
   196         }
   197     }
   198 
   199 private:
   200     PEP_SESSION m_session;
   201     mutex session_mutex;
   202     atomic< identity_queue_t * > identity_queue;
   203     thread *keymanagement_thread;
   204     bool verbose_mode;
   205 
   206 	mutex callback_mutex;
   207 	vector<IpEpEngineCallbacks*> callback_vector;
   208 
   209 	// Keysync members
   210     static int inject_sync_msg(void *msg, void* management);
   211     static void* retreive_next_sync_msg(void* management);
   212     void start_keysync();
   213     void stop_keysync();
   214 
   215     std::mutex keysync_mutex;
   216     std::condition_variable keysync_condition;
   217     std::thread *keysync_thread = NULL;
   218     std::queue<void*> keysync_queue;
   219     bool keysync_thread_running = false;
   220     bool keysync_abort_requested = false;
   221     PEP_SESSION keysync_session;
   222 
   223 public:
   224     // runtime config of the adapter
   225 
   226     STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
   227 
   228     // runtime config of the engine
   229 
   230     STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
   231     STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
   232 
   233     // basic API
   234 
   235     STDMETHOD(log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
   236     STDMETHOD(decrypt)(BSTR ctext, BSTR * ptext, LPSAFEARRAY * key_list, pEpStatus * decrypt_status);
   237     STDMETHOD(decrypt_b)(BSTR ctext, LPSAFEARRAY * ptext, LPSAFEARRAY * key_list, pEpStatus * decrypt_status);
   238     STDMETHOD(encrypt)(SAFEARRAY * key_list, BSTR ptext, BSTR * ctext, pEpStatus * status);
   239     STDMETHOD(encrypt_b)(SAFEARRAY * key_list, SAFEARRAY * ptext, BSTR * ctext, pEpStatus * status);
   240     STDMETHOD(trustword)(LONG value, BSTR lang, BSTR * word);
   241     STDMETHOD(TrustWords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
   242     STDMETHOD(get_identity)(BSTR address, BSTR user_id, pEpIdentity * ident);
   243     STDMETHOD(set_identity)(pEpIdentity * ident);
   244     STDMETHOD(generate_keypair)(pEpIdentity * ident, BSTR * fpr);
   245     STDMETHOD(delete_keypair)(BSTR fpr);
   246     STDMETHOD(import_key)(BSTR key_data);
   247     STDMETHOD(import_key_b)(SAFEARRAY * key_data);
   248     STDMETHOD(export_key)(BSTR fpr, BSTR * key_data);
   249     STDMETHOD(recv_key)(BSTR pattern);
   250     STDMETHOD(find_keys)(BSTR pattern, LPSAFEARRAY * key_list);
   251     STDMETHOD(send_key)(BSTR pattern);
   252     STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
   253     STDMETHOD(GetEngineVersion)(BSTR * engine_version);
   254     STDMETHOD(GetLanguagelist)(BSTR * languages);
   255     STDMETHOD(get_phrase)(BSTR lang, LONG phrase_id, BSTR * phrase);
   256 
   257     // keymanagement API
   258 
   259     STDMETHOD(StartKeyserverLookup)();
   260     STDMETHOD(StopKeyserverLookup)();
   261 
   262     STDMETHOD(examine_identity)(pEpIdentity * ident);
   263     STDMETHOD(verify)(BSTR text, BSTR signature, LPSAFEARRAY * key_list, pEpStatus * verify_status);
   264     STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
   265     STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
   266     STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
   267     STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
   268     STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
   269 
   270 
   271     // Blacklist API
   272 
   273     STDMETHOD(BlacklistAdd)(BSTR fpr);
   274     STDMETHOD(BlacklistDelete)(BSTR fpr);
   275     STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
   276     STDMETHOD(BlacklistRetreive)(SAFEARRAY **blacklist);
   277 
   278     // Message API
   279 
   280     STDMETHOD(EncryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY * extra, pEpEncryptFlags flags);
   281     STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
   282     STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
   283     STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
   284 	STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
   285 
   286 	// Event callbacks
   287 
   288 	STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
   289 	STDMETHOD(UnregisterCallbacks)(IpEpEngineCallbacks *obsolete_callback);
   290 
   291     // PGP compatibility functions
   292     STDMETHOD(OpenPGP_list_keyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
   293 
   294 protected:
   295 	HRESULT Fire_MessageToSend(
   296 		/* [in] */ struct TextMessage *msg);
   297 
   298 	HRESULT Fire_ShowHandshake(
   299 		/* [in] */ struct pEpIdentity *self,
   300 		/* [in] */ struct pEpIdentity *partner,
   301 		/* [retval][out] */ SyncHandshakeResult *result);
   302 };
   303 
   304 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)