CpEpEngine.h
author Markus Schaber <markus@pep-security.net>
Mon, 03 Oct 2016 22:06:35 +0200
branchkeysync
changeset 172 112b0fac353d
parent 169 d776268c12a7
child 175 9aabb2c9df08
permissions -rw-r--r--
COM-30 COM-24: Refactorings
Adapt naming convention for Methods, Types and Enum members
Remove obsolete methods
Also defined new GUIDs for all types, which is also necessary for COM-29.
     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         ::register_sync_callbacks(m_session, (void*)this, messageToSend, showHandshake, inject_sync_msg, retreive_next_sync_msg);
    90         ::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
    91     }
    92 
    93     ~CpEpEngine()
    94     {
    95         stop_keysync();
    96         StopKeyserverLookup();
    97         ::unregister_sync_callbacks(m_session);
    98         ::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
    99         ::release(m_session);
   100     }
   101 
   102 DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
   103 
   104 DECLARE_NOT_AGGREGATABLE(CpEpEngine)
   105 
   106 BEGIN_COM_MAP(CpEpEngine)
   107     COM_INTERFACE_ENTRY(IpEpEngine)
   108     COM_INTERFACE_ENTRY(ISupportErrorInfo)
   109 END_COM_MAP()
   110 
   111 // ISupportsErrorInfo
   112 	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
   113 
   114 
   115 	DECLARE_PROTECT_FINAL_CONSTRUCT()
   116 
   117 	HRESULT FinalConstruct()
   118 	{
   119 		return S_OK;
   120 	}
   121 
   122 	void FinalRelease()
   123 	{
   124 	}
   125 
   126 
   127 protected:
   128     class session
   129     {
   130     private:
   131         CpEpEngine *me;
   132 
   133     public:
   134         session(CpEpEngine *myself)
   135         {
   136             me = myself;
   137             me->session_mutex.lock();
   138         }
   139 
   140         ~session()
   141         {
   142             me->session_mutex.unlock();
   143         }
   144 
   145         operator PEP_SESSION const ()
   146         {
   147             return me->m_session;
   148         }
   149     };
   150 
   151     session get_session()
   152     {
   153         return session(this);
   154     }
   155 
   156 	class callbacks
   157 	{
   158 	private:
   159 		CpEpEngine *me;
   160 
   161 	public:
   162 		callbacks(CpEpEngine *myself)
   163 		{
   164 			me = myself;
   165 			me->callback_mutex.lock();
   166 		}
   167 
   168 		~callbacks()
   169 		{
   170 			me->callback_mutex.unlock();
   171 		}
   172 
   173 		operator vector<IpEpEngineCallbacks *>& ()
   174 		{
   175 			return me->callback_vector;
   176 		}
   177 	};
   178 
   179 	callbacks get_callbacks()
   180 	{
   181 		return callbacks(this);
   182 	}
   183 
   184     typedef locked_queue<pEp_identity_cpp> identity_queue_t;
   185     static ::pEp_identity * retrieve_next_identity(void *management);
   186     static PEP_STATUS messageToSend(void * obj, message *msg);
   187     static PEP_STATUS showHandshake(void * obj, pEp_identity *self, pEp_identity *partner);
   188 
   189 
   190     HRESULT error(_bstr_t msg);
   191 
   192     void verbose(string text)
   193     {
   194         if (verbose_mode) {
   195             stringstream ss;
   196             ss << __FILE__ << ":" << __LINE__ << " " << text;
   197             ::log_event(get_session(), "verbose", "pEp COM Server Adapter", ss.str().c_str(), NULL);
   198         }
   199     }
   200 
   201 private:
   202     PEP_SESSION m_session;
   203     mutex session_mutex;
   204     atomic< identity_queue_t * > identity_queue;
   205     thread *keymanagement_thread;
   206     bool verbose_mode;
   207 
   208 	mutex callback_mutex;
   209 	vector<IpEpEngineCallbacks*> callback_vector;
   210 
   211 	// Keysync members
   212     static int inject_sync_msg(void *msg, void* management);
   213     static void* retreive_next_sync_msg(void* management);
   214     void start_keysync();
   215     void stop_keysync();
   216 
   217     std::mutex keysync_mutex;
   218     std::condition_variable keysync_condition;
   219     std::thread *keysync_thread = NULL;
   220     std::queue<void*> keysync_queue;
   221     bool keysync_thread_running = false;
   222     bool keysync_abort_requested = false;
   223     PEP_SESSION keysync_session;
   224 
   225 public:
   226     // runtime config of the adapter
   227 
   228     STDMETHOD(VerboseLogging)(VARIANT_BOOL enable);
   229 
   230     // runtime config of the engine
   231 
   232     STDMETHOD(PassiveMode)(VARIANT_BOOL enable);
   233     STDMETHOD(UnencryptedSubject)(VARIANT_BOOL enable);
   234 
   235     // basic API
   236 
   237     STDMETHOD(log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
   238     STDMETHOD(decrypt)(BSTR ctext, BSTR * ptext, LPSAFEARRAY * key_list, pEpStatus * decrypt_status);
   239     STDMETHOD(decrypt_b)(BSTR ctext, LPSAFEARRAY * ptext, LPSAFEARRAY * key_list, pEpStatus * decrypt_status);
   240     STDMETHOD(encrypt)(SAFEARRAY * key_list, BSTR ptext, BSTR * ctext, pEpStatus * status);
   241     STDMETHOD(encrypt_b)(SAFEARRAY * key_list, SAFEARRAY * ptext, BSTR * ctext, pEpStatus * status);
   242     STDMETHOD(trustword)(LONG value, BSTR lang, BSTR * word);
   243     STDMETHOD(TrustWords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
   244     STDMETHOD(get_identity)(BSTR address, BSTR user_id, pEpIdentity * ident);
   245     STDMETHOD(set_identity)(pEpIdentity * ident);
   246     STDMETHOD(generate_keypair)(pEpIdentity * ident, BSTR * fpr);
   247     STDMETHOD(delete_keypair)(BSTR fpr);
   248     STDMETHOD(import_key)(BSTR key_data);
   249     STDMETHOD(import_key_b)(SAFEARRAY * key_data);
   250     STDMETHOD(export_key)(BSTR fpr, BSTR * key_data);
   251     STDMETHOD(recv_key)(BSTR pattern);
   252     STDMETHOD(find_keys)(BSTR pattern, LPSAFEARRAY * key_list);
   253     STDMETHOD(send_key)(BSTR pattern);
   254     STDMETHOD(GetCrashdumpLog)(LONG maxlines, BSTR * log);
   255     STDMETHOD(GetEngineVersion)(BSTR * engine_version);
   256     STDMETHOD(GetLanguagelist)(BSTR * languages);
   257     STDMETHOD(get_phrase)(BSTR lang, LONG phrase_id, BSTR * phrase);
   258 
   259     // keymanagement API
   260 
   261     STDMETHOD(StartKeyserverLookup)();
   262     STDMETHOD(StopKeyserverLookup)();
   263 
   264     STDMETHOD(examine_identity)(pEpIdentity * ident);
   265     STDMETHOD(verify)(BSTR text, BSTR signature, LPSAFEARRAY * key_list, pEpStatus * verify_status);
   266     STDMETHOD(Myself)(struct pEpIdentity *ident, struct pEpIdentity *result);
   267     STDMETHOD(UpdateIdentity)(struct pEpIdentity *ident, struct pEpIdentity *result);
   268     STDMETHOD(KeyMistrusted)(struct pEpIdentity *ident);
   269     STDMETHOD(KeyResetTrust)(struct pEpIdentity *ident);
   270     STDMETHOD(TrustPersonalKey)(struct pEpIdentity *ident, struct pEpIdentity *result);
   271 
   272 
   273     // Blacklist API
   274 
   275     STDMETHOD(BlacklistAdd)(BSTR fpr);
   276     STDMETHOD(BlacklistDelete)(BSTR fpr);
   277     STDMETHOD(BlacklistIsListed)(BSTR fpr, VARIANT_BOOL *listed);
   278     STDMETHOD(BlacklistRetreive)(SAFEARRAY **blacklist);
   279 
   280     // Message API
   281 
   282     STDMETHOD(EncryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY * extra, pEpEncryptFlags flags);
   283     STDMETHOD(DecryptMessage)(TextMessage * src, TextMessage * dst, SAFEARRAY ** keylist, pEpDecryptFlags* flags, pEpRating *rating);
   284     STDMETHOD(OutgoingMessageRating)(TextMessage *msg, pEpRating * pVal);
   285     STDMETHOD(IdentityRating)(pEpIdentity * ident, pEpRating * pVal);
   286 	STDMETHOD(ColorFromRating)(pEpRating rating, pEpColor * pVal);
   287 
   288 	// Event callbacks
   289 
   290 	STDMETHOD(RegisterCallbacks)(IpEpEngineCallbacks *new_callback);
   291 	STDMETHOD(UnregisterCallbacks)(IpEpEngineCallbacks *obsolete_callback);
   292 
   293     // PGP compatibility functions
   294     STDMETHOD(OpenPGP_list_keyinfo)(BSTR search_pattern, LPSAFEARRAY* keyinfo_list);
   295 
   296 protected:
   297 	HRESULT Fire_MessageToSend(
   298 		/* [in] */ struct TextMessage *msg);
   299 
   300 	HRESULT Fire_ShowHandshake(
   301 		/* [in] */ struct pEpIdentity *self,
   302 		/* [in] */ struct pEpIdentity *partner,
   303 		/* [retval][out] */ SyncHandshakeResult *result);
   304 };
   305 
   306 OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)