COM-49: When system.db is missing, adapter keeps restaring in a loop with no error message.
authorMarkus Schaber <markus@pep-security.net>
Thu, 01 Feb 2018 23:30:55 +0100
changeset 2684d41410af9a0
parent 264 aa6bd84bd6c3
child 269 26c8597fe860
COM-49: When system.db is missing, adapter keeps restaring in a loop with no error message.

- Move most initialization work from constructor to FinalConstruct(), where
we can (at least) return an error code.

- Fix null dereference crashes in destructor when FinalConstruct() failed.

- Generally preserve the PEP_STATUS via FACILITY_ITF HRESULTs (except OOM,
which results in an OutOfMemoryException via E_OUTOFMEMORY).

- Add pEpStatus enum to IDL file, so the client can (potentially) use it to make
more sense out of the HRESULTs.
CpEpEngine.cpp
CpEpEngine.h
pEpCOMServerAdapter.idl
     1.1 --- a/CpEpEngine.cpp	Fri Dec 01 19:38:09 2017 +0100
     1.2 +++ b/CpEpEngine.cpp	Thu Feb 01 23:30:55 2018 +0100
     1.3 @@ -8,6 +8,10 @@
     1.4  using namespace pEp::utility;
     1.5  
     1.6  // CpEpEngine
     1.7 +
     1.8 +// the init_mutex protects our initialization and destruction
     1.9 +// against a running keysync thread, and it ensures that the
    1.10 +// keysync thread actually has finished before we're destructed.
    1.11  std::mutex CpEpEngine::init_mutex;
    1.12  
    1.13  STDMETHODIMP CpEpEngine::InterfaceSupportsErrorInfo(REFIID riid)
    1.14 @@ -826,7 +830,7 @@
    1.15      if (status == ::PEP_OUT_OF_MEMORY)
    1.16          return E_OUTOFMEMORY;
    1.17  
    1.18 -    return E_FAIL;
    1.19 +    return MAKE_HRESULT(1, FACILITY_ITF, (0xFFFF & status));
    1.20  }
    1.21  
    1.22  STDMETHODIMP CpEpEngine::EncryptMessage(TextMessage * src, TextMessage * dst, SAFEARRAY * extra, pEpEncryptFlags flags)
     2.1 --- a/CpEpEngine.h	Fri Dec 01 19:38:09 2017 +0100
     2.2 +++ b/CpEpEngine.h	Thu Feb 01 23:30:55 2018 +0100
     2.3 @@ -33,21 +33,20 @@
     2.4  public:
     2.5      CpEpEngine() : keymanagement_thread(NULL), identity_queue(NULL), verbose_mode(false)
     2.6  	{
     2.7 -		std::lock_guard<std::mutex> lock(init_mutex);
     2.8 -		PEP_STATUS status = ::init(&m_session);
     2.9 -		assert(status == PEP_STATUS_OK);
    2.10 -
    2.11 -        ::register_examine_function(m_session, CpEpEngine::examine_identity, (void *)this);
    2.12 -        ::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
    2.13 -    }
    2.14 +		// See FinalConstruct() below for most initialization work, and an
    2.15 +		// explanation why it had to be moved there...
    2.16 +    }	
    2.17  
    2.18      ~CpEpEngine()
    2.19      {
    2.20          stop_keysync();
    2.21          StopKeyserverLookup();
    2.22 -        ::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
    2.23 -		std::lock_guard<std::mutex> lock(init_mutex);
    2.24 -		::release(m_session);
    2.25 +		if (m_session) // may be zero when FinalConstruct failed to initialize the engine
    2.26 +		{
    2.27 +			::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
    2.28 +			std::lock_guard<std::mutex> lock(init_mutex);
    2.29 +			::release(m_session);
    2.30 +		}
    2.31      }
    2.32  
    2.33  DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
    2.34 @@ -63,11 +62,26 @@
    2.35  // ISupportsErrorInfo
    2.36  	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    2.37  
    2.38 -
    2.39  	DECLARE_PROTECT_FINAL_CONSTRUCT()
    2.40  
    2.41 +	// Unfortunately, neither FAIL nor error() work in the constructor, as 
    2.42 +	// CreateErrorInfo/SetErrorInfo cannot work when the instance is not constructed.
    2.43 +	// AtlThrow works, but the exception is caught in CComCreator.CreateInstance, and
    2.44 +	// unconditionally turned into E_OUTOFMEMORY. Thus, we need to do most constructor
    2.45 +	// work in FinalConstruct. CreateErrorInfo/SetErrorInfo still won't work, but at least,
    2.46 +	// we can return a meaningful HRESULT. Thus, we pack our PEP_STATUS into a custom HRESULT.	
    2.47  	HRESULT FinalConstruct()
    2.48  	{
    2.49 +		std::lock_guard<std::mutex> lock(init_mutex);
    2.50 +		PEP_STATUS status = ::init(&m_session);
    2.51 +		assert(status == PEP_STATUS_OK);
    2.52 +		if (status != PEP_STATUS_OK) {
    2.53 +			HRESULT res = MAKE_HRESULT(1, FACILITY_ITF, (0xFFFF & status));
    2.54 +			return res;
    2.55 +		}
    2.56 +
    2.57 +		::register_examine_function(m_session, CpEpEngine::examine_identity, (void *)this);
    2.58 +		::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
    2.59  		return S_OK;
    2.60  	}
    2.61  
     3.1 --- a/pEpCOMServerAdapter.idl	Fri Dec 01 19:38:09 2017 +0100
     3.2 +++ b/pEpCOMServerAdapter.idl	Thu Feb 01 23:30:55 2018 +0100
     3.3 @@ -1,349 +1,437 @@
     3.4 -// pEpCOMServerAdapter.idl : IDL source for pEpCOMServerAdapter
     3.5 -//
     3.6 -
     3.7 -// This file will be processed by the MIDL tool to
     3.8 -// produce the type library (pEpCOMServerAdapter.tlb) and marshalling code.
     3.9 -
    3.10 -import "oaidl.idl";
    3.11 -import "ocidl.idl";
    3.12 -
    3.13 -[
    3.14 -    object,
    3.15 -    uuid(4DA92647-A858-448E-B01F-BE4DCB8C86A1),
    3.16 -    oleautomation,
    3.17 -    nonextensible,
    3.18 -    pointer_default(unique)
    3.19 -]
    3.20 -interface IpEpEngineCallbacks : IUnknown {
    3.21 -    typedef [v1_enum] enum SyncHandshakeSignal {
    3.22 -        SyncNotifyUndefined = 0,
    3.23 -
    3.24 -        // request show handshake dialog
    3.25 -        SyncNotifyInitAddOurDevice = 1,
    3.26 -        SyncNotifyInitAddOtherDevice = 2,
    3.27 -        SyncNotifyInitFormGroup = 3,
    3.28 -        SyncNotifyInitMoveOurDevice = 4,
    3.29 -
    3.30 -        // handshake process timed out
    3.31 -        SyncNotifyTimeout = 5,
    3.32 -
    3.33 -        // handshake accepted by user
    3.34 -        SyncNotifyAcceptedDeviceAdded = 6,
    3.35 -        SyncNotifyAcceptedGroupCreated = 7,
    3.36 -        SyncNotifyAcceptedDeviceMoved = 8,
    3.37 -
    3.38 -        // handshake dialog must be closed
    3.39 -        SyncNotifyOvertaken = 9,
    3.40 -    } SyncHandshakeSignal;
    3.41 -
    3.42 -    typedef [v1_enum] enum SyncHandshakeResult {
    3.43 -        SyncHandshakeCancel = -1,
    3.44 -        SyncHandshakeAccepted = 0,
    3.45 -        SyncHandshakeRejected = 1
    3.46 -    } SyncHandshakeResult;
    3.47 -
    3.48 -    [id(1)] HRESULT MessageToSend([in] struct TextMessage * msg);
    3.49 -    [id(2)] HRESULT NotifyHandshake([in] struct pEpIdentity * self, [in] struct pEpIdentity * partner, [in] SyncHandshakeSignal signal, [out, retval] SyncHandshakeResult * result);
    3.50 -};
    3.51 -
    3.52 -[
    3.53 -    object,
    3.54 -    uuid(64E964B2-880A-4E92-B0B5-66FF4286A3B3),
    3.55 -    oleautomation,
    3.56 -    nonextensible,
    3.57 -    pointer_default(unique)
    3.58 -]
    3.59 -interface IpEpEngineCallbacks2 : IpEpEngineCallbacks 
    3.60 -{
    3.61 -    [id(3)] HRESULT NeedFastPolling([in] VARIANT_BOOL enableFastPolling);
    3.62 -};
    3.63 -
    3.64 -[
    3.65 -    object,
    3.66 -    uuid(045E49AF-0975-4876-A53B-8CA5AB28C0F8),
    3.67 -    oleautomation,
    3.68 -    nonextensible,
    3.69 -    pointer_default(unique)
    3.70 -]
    3.71 -interface IpEpEngine : IUnknown {
    3.72 -
    3.73 -    // runtime config of the adapter
    3.74 -
    3.75 -    HRESULT VerboseLogging([in] VARIANT_BOOL enable);
    3.76 -
    3.77 -    // runtime config of the engine
    3.78 -
    3.79 -    HRESULT PassiveMode([in] VARIANT_BOOL enable);
    3.80 -    HRESULT UnencryptedSubject([in] VARIANT_BOOL enable);
    3.81 -
    3.82 -    // basic API
    3.83 -
    3.84 -    HRESULT ExportKey([in] BSTR fpr, [out, retval] BSTR * keyData);
    3.85 -    HRESULT Log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment);
    3.86 -    HRESULT Trustwords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG maxWords, [out, retval] BSTR * words);
    3.87 -    HRESULT GetTrustwords([in] struct pEpIdentity * id1, [in] struct pEpIdentity * id2, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] VARIANT_BOOL full, [out, retval] BSTR * words);
    3.88 -    HRESULT GetCrashdumpLog([in, defaultvalue(0)] LONG maxlines, [out, retval] BSTR * log);
    3.89 -    HRESULT GetEngineVersion([out, retval] BSTR * engineVersion);
    3.90 -    HRESULT GetLanguageList([out, retval] BSTR * languages);
    3.91 -
    3.92 -    typedef [v1_enum] enum pEpComType {
    3.93 -        pEpCtUnknown = 0,
    3.94 -
    3.95 -        // range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable
    3.96 -
    3.97 -        pEpCtNoEncryption = 0x01,                // generic
    3.98 -        pEpCtNoEncryptedChannel = 0x02,
    3.99 -        pEpCtKeyNotFound = 0x03,
   3.100 -        pEpCtKeyExpired = 0x04,
   3.101 -        pEpCtKeyRevoked = 0x05,
   3.102 -        pEpCtKeyB0rken = 0x06,
   3.103 -        pEpCtMyKeyNotIncluded = 0x09,
   3.104 -
   3.105 -        pEpCtSecurityByObscurity = 0x0a,
   3.106 -        pEpCtB0rkenCrypto = 0x0b,
   3.107 -        pEpCtKeyTooShort = 0x0c,
   3.108 -
   3.109 -        pEpCtCompromised = 0x0e,                 // known compromized connection
   3.110 -        pEpCtMistrusted = 0x0f,                  // known mistrusted key
   3.111 -
   3.112 -        // range 0x10 to 0x3f: unconfirmed encryption
   3.113 -
   3.114 -        pEpCtUnconfirmedEncryption = 0x10,       // generic
   3.115 -        pEpCtOpenPGPWeakUnconfirmed = 0x11,      // RSA 1024 is weak
   3.116 -
   3.117 -        pEpCtToBeChecked = 0x20,                 // generic
   3.118 -        pEpCtSMIMEUnconfirmed = 0x21,
   3.119 -        pEpCtCMSUnconfirmed = 0x22,
   3.120 -
   3.121 -        pEpCtStrongButUnconfirmed = 0x30,        // generic
   3.122 -        pEpCtOpenPGPUnconfirmed = 0x38,          // key at least 2048 bit RSA or EC
   3.123 -        pEpCtOTRUnconfirmed = 0x3a,
   3.124 -
   3.125 -        // range 0x40 to 0x7f: unconfirmed encryption and anonymization
   3.126 -
   3.127 -        pEpCtUnconfirmedEncAnon = 0x40,          // generic
   3.128 -        pEpCtpEpUnconfirmed = 0x7f,
   3.129 -
   3.130 -        pEpCtConfirmed = 0x80,                   // this bit decides if trust is confirmed
   3.131 -
   3.132 -        // range 0x81 to 0x8f: reserved
   3.133 -        // range 0x90 to 0xbf: confirmed encryption
   3.134 -
   3.135 -        pEpCtConfirmedEncryption = 0x90,         // generic
   3.136 -        pEpCtOpenPGPWeak = 0x91,                 // RSA 1024 is weak
   3.137 -
   3.138 -        pEpCtToBeCheckedConfirmed = 0xa0,        // generic
   3.139 -        pEpCtSMIME = 0xa1,
   3.140 -        pEpCtCMS = 0xa2,
   3.141 -
   3.142 -        pEpCtStrongEncryption = 0xb0,            // generic
   3.143 -        pEpCtOpenPGP = 0xb8,                     // key at least 2048 bit RSA or EC
   3.144 -        pEpCtOTR = 0xba,
   3.145 -
   3.146 -        // range 0xc0 to 0xff: confirmed encryption and anonymization
   3.147 -
   3.148 -        pEpCtConfirmedEncAnon = 0xc0,            // generic
   3.149 -        pEpCtpEp = 0xff
   3.150 -    } pEpComType;
   3.151 -
   3.152 -    typedef [v1_enum] enum pEpIdentityFlags {
   3.153 -        pEpIdfNone = 0,
   3.154 -        pEpIdfNotForSync = 0x0001,
   3.155 -        pEpIdfList = 0x0002,
   3.156 -        pEpIdfDevicegroup = 0x0100
   3.157 -    } pEpIdentityFlags;
   3.158 -
   3.159 -    [uuid(C3A3814E-567F-4D1C-9F44-9B1DA3957A89)] struct pEpIdentity {
   3.160 -        BSTR Address;
   3.161 -        BSTR Fpr;
   3.162 -        BSTR UserId;
   3.163 -        BSTR UserName;
   3.164 -        pEpComType CommType;
   3.165 -        BSTR Lang;
   3.166 -        pEpIdentityFlags Flags;
   3.167 -    };
   3.168 -
   3.169 -    HRESULT SetIdentityFlags([in] struct pEpIdentity *identity, [in] pEpIdentityFlags flags);
   3.170 -    HRESULT UnsetIdentityFlags([in] struct pEpIdentity *identity, [in] pEpIdentityFlags flags);
   3.171 -
   3.172 -    // Keymanagement API
   3.173 -
   3.174 -    HRESULT StartKeyserverLookup();
   3.175 -    HRESULT StopKeyserverLookup();
   3.176 -
   3.177 -    HRESULT Myself([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.178 -    HRESULT UpdateIdentity([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.179 -    HRESULT KeyMistrusted([in] struct pEpIdentity *ident);
   3.180 -    HRESULT KeyResetTrust([in] struct pEpIdentity *ident);
   3.181 -    HRESULT TrustPersonalKey([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.182 -    HRESULT OwnIdentitiesRetrieve([out, retval] SAFEARRAY(struct pEpIdentity)* ownIdentities);
   3.183 -
   3.184 -    // Blacklist API
   3.185 -
   3.186 -    HRESULT BlacklistAdd([in] BSTR fpr);
   3.187 -    HRESULT BlacklistDelete([in] BSTR fpr);
   3.188 -    HRESULT BlacklistIsListed([in] BSTR fpr, [out, retval] VARIANT_BOOL *listed);
   3.189 -    HRESULT BlacklistRetrieve([out, retval] SAFEARRAY(BSTR) *blacklist);
   3.190 -
   3.191 -    // PGP compatibility functions
   3.192 -
   3.193 -    HRESULT OpenPGPListKeyinfo([in] BSTR searchPattern, [out, retval] SAFEARRAY(struct StringPair)* keyinfoList);
   3.194 -
   3.195 -    // Message API
   3.196 -
   3.197 -    typedef [v1_enum] enum pEpRating {
   3.198 -        pEpRatingUndefined = 0,
   3.199 -        pEpRatingCannotDecrypt,
   3.200 -        pEpRatingHaveNoKey,
   3.201 -        pEpRatingUnencrypted,
   3.202 -        pEpRatingUnencryptedForSome,
   3.203 -        pEpRatingUnreliable,
   3.204 -        pEpRatingReliable,
   3.205 -        pEpRatingTrusted,
   3.206 -        pEpRatingTrustedAndAnonymized,
   3.207 -        pEpRatingFullyAnonymous,
   3.208 -
   3.209 -        pEpRatingMistrust = -1,
   3.210 -        pEpRatingB0rken = -2,
   3.211 -        pEpRatingUnderAttack = -3
   3.212 -    } pEpRating;
   3.213 -
   3.214 -    typedef [v1_enum] enum pEpColor {
   3.215 -        pEpColorNoColor = 0,
   3.216 -        pEpColorYellow,
   3.217 -        pEpColorGreen,
   3.218 -        pEpColorRed = -1,
   3.219 -    } pEpColor;
   3.220 -
   3.221 -    typedef [v1_enum] enum pEpEncryptFlags {
   3.222 -        pEpEncryptFlagDefault = 0,
   3.223 -        pEpEncryptFlagForceEncryption = 0x1,
   3.224 -
   3.225 -        // This flag is for special uses and should not be used
   3.226 -        // by normal pEp clients!
   3.227 -        pEpEncryptFlagForceUnsigned = 0x2,
   3.228 -
   3.229 -        // This flag is for special uses and should not be used
   3.230 -        // by normal pEp clients!
   3.231 -        pEpEncryptFlagForceNoAttachedKey = 0x4,
   3.232 -
   3.233 -    } pEpEncryptFlags;
   3.234 -
   3.235 -    typedef [v1_enum] enum pEpDecryptFlags {
   3.236 -        pEpDecryptFlagsNone = 0,
   3.237 -        pEpDecryptFlagOwnPrivateKey = 0x1,
   3.238 -        pEpDecryptFlagConsume = 0x2,
   3.239 -        pEpDecryptFlagIgnore = 0x4
   3.240 -    } pEpDecryptFlags;
   3.241 -
   3.242 -    typedef [v1_enum] enum pEpMsgDirection {
   3.243 -        pEpDirIncoming = 0,
   3.244 -        pEpDirOutgoing
   3.245 -    } pEpMsgDirection;
   3.246 -
   3.247 -    [uuid(47FB0795-6B64-455C-BB0E-54998CAB8ACB)] struct StringPair {
   3.248 -        BSTR Name;
   3.249 -        BSTR Value;
   3.250 -    };
   3.251 -
   3.252 -    [uuid(634EB7CE-99AA-460D-BDF8-F7CDA7232CA6)] struct Blob {
   3.253 -        SAFEARRAY(BYTE) value;
   3.254 -        BSTR MimeType;
   3.255 -        BSTR Filename;
   3.256 -    };
   3.257 -
   3.258 -    [uuid(B6F40887-E761-4A47-B204-A0193EE0284D)] struct TextMessage {
   3.259 -        pEpMsgDirection Dir;
   3.260 -        BSTR Id;
   3.261 -        BSTR ShortMsg;
   3.262 -        BSTR LongMsg;
   3.263 -        BSTR LongMsgFormatted;
   3.264 -        SAFEARRAY(struct Blob) Attachments;
   3.265 -        hyper Sent; // Timestamp: 64 Bit time_t from mktime(), seconds since January 1, 1970, 0:00 UTC.
   3.266 -        hyper Recv; // Timestamp: 64 Bit time_t from mktime(), seconds since January 1, 1970, 0:00 UTC.
   3.267 -        struct pEpIdentity From;
   3.268 -        SAFEARRAY(struct pEpIdentity) To;
   3.269 -        struct pEpIdentity RecvBy;
   3.270 -        SAFEARRAY(struct pEpIdentity) Cc;
   3.271 -        SAFEARRAY(struct pEpIdentity) Bcc;
   3.272 -        SAFEARRAY(struct pEpIdentity) ReplyTo;
   3.273 -        SAFEARRAY(BSTR) References;
   3.274 -        SAFEARRAY(BSTR) Keywords;
   3.275 -        BSTR Comments;
   3.276 -        SAFEARRAY(struct StringPair) OptFields;
   3.277 -    };
   3.278 -
   3.279 -    HRESULT EncryptMessage(
   3.280 -        [in] struct TextMessage *src,
   3.281 -        [out] struct TextMessage * dst,
   3.282 -        [in] SAFEARRAY(BSTR) extra,
   3.283 -        [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags);
   3.284 -
   3.285 -    HRESULT DecryptMessage(
   3.286 -        [in] struct TextMessage *src,
   3.287 -        [out] struct TextMessage * dst,
   3.288 -        [out] SAFEARRAY(BSTR) *keylist,
   3.289 -        [out] pEpDecryptFlags* flags,
   3.290 -        [out, retval] pEpRating *rating);
   3.291 -
   3.292 -    HRESULT OutgoingMessageRating([in] struct TextMessage *msg, [out, retval] pEpRating * pVal);
   3.293 -    HRESULT IdentityRating([in] struct pEpIdentity * ident, [out, retval] pEpRating * pVal);
   3.294 -    HRESULT ColorFromRating([in] pEpRating rating, [out, retval] pEpColor* pVal);
   3.295 -
   3.296 -    // callback / keysync API
   3.297 -    HRESULT RegisterCallbacks([in] IpEpEngineCallbacks* newCallback);
   3.298 -    HRESULT UnregisterCallbacks();
   3.299 -};
   3.300 -
   3.301 -[
   3.302 -    object,
   3.303 -    uuid(8A042123-D433-4DEA-ADA2-2E5E61A00292),
   3.304 -    oleautomation,
   3.305 -    nonextensible,
   3.306 -    pointer_default(unique)
   3.307 -]
   3.308 -interface IpEpEngine2 : IpEpEngine
   3.309 -{
   3.310 -    HRESULT GetMessageTrustwords(
   3.311 -        [in] struct TextMessage *msg,
   3.312 -        [in] struct pEpIdentity * receivedBy,
   3.313 -        [in] SAFEARRAY(BSTR) keylist,
   3.314 -        [in, defaultvalue("en")] BSTR lang,
   3.315 -        [in, defaultvalue(0)] VARIANT_BOOL full,
   3.316 -        [out, retval] BSTR * words
   3.317 -    );
   3.318 -
   3.319 -    HRESULT EncryptMessageForSelf(
   3.320 -        [in] struct pEpIdentity* targetId,
   3.321 -        [in] struct TextMessage* src, 
   3.322 -        [out] struct TextMessage* dst,
   3.323 -        [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags
   3.324 -    );
   3.325 -
   3.326 -    HRESULT ReEvaluateMessageRating(
   3.327 -        [in] struct TextMessage *src,
   3.328 -        [in] SAFEARRAY(BSTR) x_KeyList, // referring to X-KeyList mail header
   3.329 -        [in] pEpRating x_EncStatus, // referring to X-EncStatus mail header
   3.330 -        [out, retval] pEpRating *rating
   3.331 -    );
   3.332 -
   3.333 -	HRESULT UndoLastMistrust();
   3.334 -};
   3.335 -
   3.336 -[
   3.337 -    uuid(564A4350-419E-47F1-B0DF-6FCCF0CD0BBC),
   3.338 -    version(1.0),
   3.339 -]
   3.340 -library pEpCOMServerAdapterLib
   3.341 -{
   3.342 -    importlib("stdole2.tlb");
   3.343 -
   3.344 -    [
   3.345 -        uuid(5FF6682B-727B-4DFE-A68D-28982874C0C7)
   3.346 -    ]
   3.347 -    coclass pEpEngine {
   3.348 -        [default] interface IpEpEngine2;
   3.349 -        interface IpEpEngine;
   3.350 -        interface IpEpEngineCallbacks2;
   3.351 -    };
   3.352 -};
   3.353 +// pEpCOMServerAdapter.idl : IDL source for pEpCOMServerAdapter
   3.354 +//
   3.355 +
   3.356 +// This file will be processed by the MIDL tool to
   3.357 +// produce the type library (pEpCOMServerAdapter.tlb) and marshalling code.
   3.358 +
   3.359 +import "oaidl.idl";
   3.360 +import "ocidl.idl";
   3.361 +
   3.362 +[
   3.363 +    object,
   3.364 +    uuid(4DA92647-A858-448E-B01F-BE4DCB8C86A1),
   3.365 +    oleautomation,
   3.366 +    nonextensible,
   3.367 +    pointer_default(unique)
   3.368 +]
   3.369 +interface IpEpEngineCallbacks : IUnknown {
   3.370 +    typedef [v1_enum] enum SyncHandshakeSignal {
   3.371 +        SyncNotifyUndefined = 0,
   3.372 +
   3.373 +        // request show handshake dialog
   3.374 +        SyncNotifyInitAddOurDevice = 1,
   3.375 +        SyncNotifyInitAddOtherDevice = 2,
   3.376 +        SyncNotifyInitFormGroup = 3,
   3.377 +        SyncNotifyInitMoveOurDevice = 4,
   3.378 +
   3.379 +        // handshake process timed out
   3.380 +        SyncNotifyTimeout = 5,
   3.381 +
   3.382 +        // handshake accepted by user
   3.383 +        SyncNotifyAcceptedDeviceAdded = 6,
   3.384 +        SyncNotifyAcceptedGroupCreated = 7,
   3.385 +        SyncNotifyAcceptedDeviceMoved = 8,
   3.386 +
   3.387 +        // handshake dialog must be closed
   3.388 +        SyncNotifyOvertaken = 9,
   3.389 +    } SyncHandshakeSignal;
   3.390 +
   3.391 +    typedef [v1_enum] enum SyncHandshakeResult {
   3.392 +        SyncHandshakeCancel = -1,
   3.393 +        SyncHandshakeAccepted = 0,
   3.394 +        SyncHandshakeRejected = 1
   3.395 +    } SyncHandshakeResult;
   3.396 +
   3.397 +    [id(1)] HRESULT MessageToSend([in] struct TextMessage * msg);
   3.398 +    [id(2)] HRESULT NotifyHandshake([in] struct pEpIdentity * self, [in] struct pEpIdentity * partner, [in] SyncHandshakeSignal signal, [out, retval] SyncHandshakeResult * result);
   3.399 +};
   3.400 +
   3.401 +[
   3.402 +    object,
   3.403 +    uuid(64E964B2-880A-4E92-B0B5-66FF4286A3B3),
   3.404 +    oleautomation,
   3.405 +    nonextensible,
   3.406 +    pointer_default(unique)
   3.407 +]
   3.408 +interface IpEpEngineCallbacks2 : IpEpEngineCallbacks 
   3.409 +{
   3.410 +    [id(3)] HRESULT NeedFastPolling([in] VARIANT_BOOL enableFastPolling);
   3.411 +};
   3.412 +
   3.413 +[
   3.414 +    object,
   3.415 +    uuid(045E49AF-0975-4876-A53B-8CA5AB28C0F8),
   3.416 +    oleautomation,
   3.417 +    nonextensible,
   3.418 +    pointer_default(unique)
   3.419 +]
   3.420 +interface IpEpEngine : IUnknown {
   3.421 +
   3.422 +    // runtime config of the adapter
   3.423 +
   3.424 +    HRESULT VerboseLogging([in] VARIANT_BOOL enable);
   3.425 +
   3.426 +    // runtime config of the engine
   3.427 +
   3.428 +    HRESULT PassiveMode([in] VARIANT_BOOL enable);
   3.429 +    HRESULT UnencryptedSubject([in] VARIANT_BOOL enable);
   3.430 +
   3.431 +    // basic API
   3.432 +
   3.433 +    HRESULT ExportKey([in] BSTR fpr, [out, retval] BSTR * keyData);
   3.434 +    HRESULT Log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment);
   3.435 +    HRESULT Trustwords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG maxWords, [out, retval] BSTR * words);
   3.436 +    HRESULT GetTrustwords([in] struct pEpIdentity * id1, [in] struct pEpIdentity * id2, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] VARIANT_BOOL full, [out, retval] BSTR * words);
   3.437 +    HRESULT GetCrashdumpLog([in, defaultvalue(0)] LONG maxlines, [out, retval] BSTR * log);
   3.438 +    HRESULT GetEngineVersion([out, retval] BSTR * engineVersion);
   3.439 +    HRESULT GetLanguageList([out, retval] BSTR * languages);
   3.440 +
   3.441 +    typedef [v1_enum] enum pEpComType {
   3.442 +        pEpCtUnknown = 0,
   3.443 +
   3.444 +        // range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable
   3.445 +
   3.446 +        pEpCtNoEncryption = 0x01,                // generic
   3.447 +        pEpCtNoEncryptedChannel = 0x02,
   3.448 +        pEpCtKeyNotFound = 0x03,
   3.449 +        pEpCtKeyExpired = 0x04,
   3.450 +        pEpCtKeyRevoked = 0x05,
   3.451 +        pEpCtKeyB0rken = 0x06,
   3.452 +        pEpCtMyKeyNotIncluded = 0x09,
   3.453 +
   3.454 +        pEpCtSecurityByObscurity = 0x0a,
   3.455 +        pEpCtB0rkenCrypto = 0x0b,
   3.456 +        pEpCtKeyTooShort = 0x0c,
   3.457 +
   3.458 +        pEpCtCompromised = 0x0e,                 // known compromized connection
   3.459 +        pEpCtMistrusted = 0x0f,                  // known mistrusted key
   3.460 +
   3.461 +        // range 0x10 to 0x3f: unconfirmed encryption
   3.462 +
   3.463 +        pEpCtUnconfirmedEncryption = 0x10,       // generic
   3.464 +        pEpCtOpenPGPWeakUnconfirmed = 0x11,      // RSA 1024 is weak
   3.465 +
   3.466 +        pEpCtToBeChecked = 0x20,                 // generic
   3.467 +        pEpCtSMIMEUnconfirmed = 0x21,
   3.468 +        pEpCtCMSUnconfirmed = 0x22,
   3.469 +
   3.470 +        pEpCtStrongButUnconfirmed = 0x30,        // generic
   3.471 +        pEpCtOpenPGPUnconfirmed = 0x38,          // key at least 2048 bit RSA or EC
   3.472 +        pEpCtOTRUnconfirmed = 0x3a,
   3.473 +
   3.474 +        // range 0x40 to 0x7f: unconfirmed encryption and anonymization
   3.475 +
   3.476 +        pEpCtUnconfirmedEncAnon = 0x40,          // generic
   3.477 +        pEpCtpEpUnconfirmed = 0x7f,
   3.478 +
   3.479 +        pEpCtConfirmed = 0x80,                   // this bit decides if trust is confirmed
   3.480 +
   3.481 +        // range 0x81 to 0x8f: reserved
   3.482 +        // range 0x90 to 0xbf: confirmed encryption
   3.483 +
   3.484 +        pEpCtConfirmedEncryption = 0x90,         // generic
   3.485 +        pEpCtOpenPGPWeak = 0x91,                 // RSA 1024 is weak
   3.486 +
   3.487 +        pEpCtToBeCheckedConfirmed = 0xa0,        // generic
   3.488 +        pEpCtSMIME = 0xa1,
   3.489 +        pEpCtCMS = 0xa2,
   3.490 +
   3.491 +        pEpCtStrongEncryption = 0xb0,            // generic
   3.492 +        pEpCtOpenPGP = 0xb8,                     // key at least 2048 bit RSA or EC
   3.493 +        pEpCtOTR = 0xba,
   3.494 +
   3.495 +        // range 0xc0 to 0xff: confirmed encryption and anonymization
   3.496 +
   3.497 +        pEpCtConfirmedEncAnon = 0xc0,            // generic
   3.498 +        pEpCtpEp = 0xff
   3.499 +    } pEpComType;
   3.500 +
   3.501 +        typedef enum pEpStatus {
   3.502 +                pEpStatusOk = 0,
   3.503 +
   3.504 +                pEpInitCannotLoadGpgme = 0x0110,
   3.505 +                pEpInitGpgmeInitFailed = 0x0111,
   3.506 +                pEpInitNoGpgHome = 0x0112,
   3.507 +                pEpInitNetpgpInitFailed = 0x0113,
   3.508 +                pEpInitCannotDetermineGpgVersion = 0x0114,
   3.509 +                pEpInitUnsupportedGpgVersion = 0x0115,
   3.510 +                pEpInitCannotConfigGpgAgent = 0x0116,
   3.511 +
   3.512 +                pEpInitSqlite3WithoutMutex = 0x0120,
   3.513 +                pEpInitCannotOpenDb = 0x0121,
   3.514 +                pEpInitCannotOpenSystemDb = 0x0122,
   3.515 +
   3.516 +                pEpKeyNotFound = 0x0201,
   3.517 +                pEpKeyHasAmbigName = 0x0202,
   3.518 +                pEpGetKeyFailed = 0x0203,
   3.519 +                pEpCannotExportKey = 0x0204,
   3.520 +                pEpCannotEditKey = 0x0205,
   3.521 +                pEpKeyUnsuitable = 0x0206,
   3.522 +
   3.523 +                pEpCannotFindIdentity = 0x0301,
   3.524 +                pEpCannotSetPerson = 0x0381,
   3.525 +                pEpCannotSetPgpKeypair = 0x0382,
   3.526 +                pEpCannotSetIdentity = 0x0383,
   3.527 +                pEpCannotSetTrust = 0x0384,
   3.528 +                pEpKeyBlacklisted = 0x0385,
   3.529 +                pEpCannotFindPerson = 0x0386,
   3.530 +
   3.531 +                pEpCannotFindAlias = 0x0391,
   3.532 +                pEpCannotSetAlias = 0x0392,
   3.533 +
   3.534 +                pEpUnencrypted = 0x0400,
   3.535 +                pEpVerified = 0x0401,
   3.536 +                pEpDecrypted = 0x0402,
   3.537 +                pEpDecryptedAndVerified = 0x0403,
   3.538 +                pEpDecryptWrongFormat = 0x0404,
   3.539 +                pEpDecryptNoKey = 0x0405,
   3.540 +                pEpDecryptSignatureDoesNotMatch = 0x0406,
   3.541 +                pEpVerifyNoKey = 0x0407,
   3.542 +                pEpVerifiedAndTrusted = 0x0408,
   3.543 +                pEpCannotDecryptUnknown = 0x04ff,
   3.544 +
   3.545 +                pEpTrustwordNotFound = 0x0501,
   3.546 +                pEpTrustwordsFprWrongLength = 0x0502,
   3.547 +                pEpTrustwordsDuplicateFpr = 0x0503,
   3.548 +
   3.549 +                pEpCannotCreateKey = 0x0601,
   3.550 +                pEpCannotSendKey = 0x0602,
   3.551 +
   3.552 +                pEpPhraseNotFound = 0x0701,
   3.553 +
   3.554 +                pEpSendFunctionNotRegistered = 0x0801,
   3.555 +                pEpContraintsViolated = 0x0802,
   3.556 +                pEpCannotEncode = 0x0803,
   3.557 +
   3.558 +                pEpSyncNoNotifyCallback = 0x0901,
   3.559 +                pEpSyncIllegalMessage = 0x0902,
   3.560 +                pEpSyncNoInjectCallback = 0x0903,
   3.561 +
   3.562 +                pEpSequenceViolated = 0x0970,
   3.563 +                pEpCannotIncreaseSequence = 0x0971,
   3.564 +                pEpCannotSetSequenceValue = 0x0972,
   3.565 +                pEpOwnSequence = 0x097f,
   3.566 +
   3.567 +                pEpSyncStatemachineError = 0x0980,
   3.568 +                pEpSyncNoTrust = 0x0981,
   3.569 +                pEpStatemachineInvalidState = 0x0982,
   3.570 +                pEpStatemachineInvalidEvent = 0x0983,
   3.571 +                pEpStatemachineInvalidCondition = 0x0984,
   3.572 +                pEpStatemachineInvalidAction = 0x0985,
   3.573 +                pEpStatemachineInhibitedEvent = 0x0986,
   3.574 +
   3.575 +                pEpCommitFailed = 0xff01,
   3.576 +                pEpMessageConsume = 0xff02,
   3.577 +                pEpMessageIgnore = 0xff03,
   3.578 +
   3.579 +                pEpRecordNotFound = -6,
   3.580 +                pEpCannotCreateTempFile = -5,
   3.581 +                pEpIllegalValue = -4,
   3.582 +                pEpBufferTooSmall = -3,
   3.583 +                pEpOutOfMemory = -2,
   3.584 +                pEpUnknownError = -1,
   3.585 +
   3.586 +                pEpVersionMismatch = -7,
   3.587 +        } pEpStatus;
   3.588 +
   3.589 +    typedef [v1_enum] enum pEpIdentityFlags {
   3.590 +        pEpIdfNone = 0,
   3.591 +        pEpIdfNotForSync = 0x0001,
   3.592 +        pEpIdfList = 0x0002,
   3.593 +        pEpIdfDevicegroup = 0x0100
   3.594 +    } pEpIdentityFlags;
   3.595 +
   3.596 +    [uuid(C3A3814E-567F-4D1C-9F44-9B1DA3957A89)] struct pEpIdentity {
   3.597 +        BSTR Address;
   3.598 +        BSTR Fpr;
   3.599 +        BSTR UserId;
   3.600 +        BSTR UserName;
   3.601 +        pEpComType CommType;
   3.602 +        BSTR Lang;
   3.603 +        pEpIdentityFlags Flags;
   3.604 +    };
   3.605 +
   3.606 +    HRESULT SetIdentityFlags([in] struct pEpIdentity *identity, [in] pEpIdentityFlags flags);
   3.607 +    HRESULT UnsetIdentityFlags([in] struct pEpIdentity *identity, [in] pEpIdentityFlags flags);
   3.608 +
   3.609 +    // Keymanagement API
   3.610 +
   3.611 +    HRESULT StartKeyserverLookup();
   3.612 +    HRESULT StopKeyserverLookup();
   3.613 +
   3.614 +    HRESULT Myself([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.615 +    HRESULT UpdateIdentity([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.616 +    HRESULT KeyMistrusted([in] struct pEpIdentity *ident);
   3.617 +    HRESULT KeyResetTrust([in] struct pEpIdentity *ident);
   3.618 +    HRESULT TrustPersonalKey([in] struct pEpIdentity *ident, [out, retval] struct pEpIdentity *result);
   3.619 +    HRESULT OwnIdentitiesRetrieve([out, retval] SAFEARRAY(struct pEpIdentity)* ownIdentities);
   3.620 +
   3.621 +    // Blacklist API
   3.622 +
   3.623 +    HRESULT BlacklistAdd([in] BSTR fpr);
   3.624 +    HRESULT BlacklistDelete([in] BSTR fpr);
   3.625 +    HRESULT BlacklistIsListed([in] BSTR fpr, [out, retval] VARIANT_BOOL *listed);
   3.626 +    HRESULT BlacklistRetrieve([out, retval] SAFEARRAY(BSTR) *blacklist);
   3.627 +
   3.628 +    // PGP compatibility functions
   3.629 +
   3.630 +    HRESULT OpenPGPListKeyinfo([in] BSTR searchPattern, [out, retval] SAFEARRAY(struct StringPair)* keyinfoList);
   3.631 +
   3.632 +    // Message API
   3.633 +
   3.634 +    typedef [v1_enum] enum pEpRating {
   3.635 +        pEpRatingUndefined = 0,
   3.636 +        pEpRatingCannotDecrypt,
   3.637 +        pEpRatingHaveNoKey,
   3.638 +        pEpRatingUnencrypted,
   3.639 +        pEpRatingUnencryptedForSome,
   3.640 +        pEpRatingUnreliable,
   3.641 +        pEpRatingReliable,
   3.642 +        pEpRatingTrusted,
   3.643 +        pEpRatingTrustedAndAnonymized,
   3.644 +        pEpRatingFullyAnonymous,
   3.645 +
   3.646 +        pEpRatingMistrust = -1,
   3.647 +        pEpRatingB0rken = -2,
   3.648 +        pEpRatingUnderAttack = -3
   3.649 +    } pEpRating;
   3.650 +
   3.651 +    typedef [v1_enum] enum pEpColor {
   3.652 +        pEpColorNoColor = 0,
   3.653 +        pEpColorYellow,
   3.654 +        pEpColorGreen,
   3.655 +        pEpColorRed = -1,
   3.656 +    } pEpColor;
   3.657 +
   3.658 +    typedef [v1_enum] enum pEpEncryptFlags {
   3.659 +        pEpEncryptFlagDefault = 0,
   3.660 +        pEpEncryptFlagForceEncryption = 0x1,
   3.661 +
   3.662 +        // This flag is for special uses and should not be used
   3.663 +        // by normal pEp clients!
   3.664 +        pEpEncryptFlagForceUnsigned = 0x2,
   3.665 +
   3.666 +        // This flag is for special uses and should not be used
   3.667 +        // by normal pEp clients!
   3.668 +        pEpEncryptFlagForceNoAttachedKey = 0x4,
   3.669 +
   3.670 +    } pEpEncryptFlags;
   3.671 +
   3.672 +    typedef [v1_enum] enum pEpDecryptFlags {
   3.673 +        pEpDecryptFlagsNone = 0,
   3.674 +        pEpDecryptFlagOwnPrivateKey = 0x1,
   3.675 +        pEpDecryptFlagConsume = 0x2,
   3.676 +        pEpDecryptFlagIgnore = 0x4
   3.677 +    } pEpDecryptFlags;
   3.678 +
   3.679 +    typedef [v1_enum] enum pEpMsgDirection {
   3.680 +        pEpDirIncoming = 0,
   3.681 +        pEpDirOutgoing
   3.682 +    } pEpMsgDirection;
   3.683 +
   3.684 +    [uuid(47FB0795-6B64-455C-BB0E-54998CAB8ACB)] struct StringPair {
   3.685 +        BSTR Name;
   3.686 +        BSTR Value;
   3.687 +    };
   3.688 +
   3.689 +    [uuid(634EB7CE-99AA-460D-BDF8-F7CDA7232CA6)] struct Blob {
   3.690 +        SAFEARRAY(BYTE) value;
   3.691 +        BSTR MimeType;
   3.692 +        BSTR Filename;
   3.693 +    };
   3.694 +
   3.695 +    [uuid(B6F40887-E761-4A47-B204-A0193EE0284D)] struct TextMessage {
   3.696 +        pEpMsgDirection Dir;
   3.697 +        BSTR Id;
   3.698 +        BSTR ShortMsg;
   3.699 +        BSTR LongMsg;
   3.700 +        BSTR LongMsgFormatted;
   3.701 +        SAFEARRAY(struct Blob) Attachments;
   3.702 +        hyper Sent; // Timestamp: 64 Bit time_t from mktime(), seconds since January 1, 1970, 0:00 UTC.
   3.703 +        hyper Recv; // Timestamp: 64 Bit time_t from mktime(), seconds since January 1, 1970, 0:00 UTC.
   3.704 +        struct pEpIdentity From;
   3.705 +        SAFEARRAY(struct pEpIdentity) To;
   3.706 +        struct pEpIdentity RecvBy;
   3.707 +        SAFEARRAY(struct pEpIdentity) Cc;
   3.708 +        SAFEARRAY(struct pEpIdentity) Bcc;
   3.709 +        SAFEARRAY(struct pEpIdentity) ReplyTo;
   3.710 +        SAFEARRAY(BSTR) References;
   3.711 +        SAFEARRAY(BSTR) Keywords;
   3.712 +        BSTR Comments;
   3.713 +        SAFEARRAY(struct StringPair) OptFields;
   3.714 +    };
   3.715 +
   3.716 +    HRESULT EncryptMessage(
   3.717 +        [in] struct TextMessage *src,
   3.718 +        [out] struct TextMessage * dst,
   3.719 +        [in] SAFEARRAY(BSTR) extra,
   3.720 +        [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags);
   3.721 +
   3.722 +    HRESULT DecryptMessage(
   3.723 +        [in] struct TextMessage *src,
   3.724 +        [out] struct TextMessage * dst,
   3.725 +        [out] SAFEARRAY(BSTR) *keylist,
   3.726 +        [out] pEpDecryptFlags* flags,
   3.727 +        [out, retval] pEpRating *rating);
   3.728 +
   3.729 +    HRESULT OutgoingMessageRating([in] struct TextMessage *msg, [out, retval] pEpRating * pVal);
   3.730 +    HRESULT IdentityRating([in] struct pEpIdentity * ident, [out, retval] pEpRating * pVal);
   3.731 +    HRESULT ColorFromRating([in] pEpRating rating, [out, retval] pEpColor* pVal);
   3.732 +
   3.733 +    // callback / keysync API
   3.734 +    HRESULT RegisterCallbacks([in] IpEpEngineCallbacks* newCallback);
   3.735 +    HRESULT UnregisterCallbacks();
   3.736 +};
   3.737 +
   3.738 +[
   3.739 +    object,
   3.740 +    uuid(8A042123-D433-4DEA-ADA2-2E5E61A00292),
   3.741 +    oleautomation,
   3.742 +    nonextensible,
   3.743 +    pointer_default(unique)
   3.744 +]
   3.745 +interface IpEpEngine2 : IpEpEngine
   3.746 +{
   3.747 +    HRESULT GetMessageTrustwords(
   3.748 +        [in] struct TextMessage *msg,
   3.749 +        [in] struct pEpIdentity * receivedBy,
   3.750 +        [in] SAFEARRAY(BSTR) keylist,
   3.751 +        [in, defaultvalue("en")] BSTR lang,
   3.752 +        [in, defaultvalue(0)] VARIANT_BOOL full,
   3.753 +        [out, retval] BSTR * words
   3.754 +    );
   3.755 +
   3.756 +    HRESULT EncryptMessageForSelf(
   3.757 +        [in] struct pEpIdentity* targetId,
   3.758 +        [in] struct TextMessage* src, 
   3.759 +        [out] struct TextMessage* dst,
   3.760 +        [in, defaultvalue(pEpEncryptFlagDefault)] pEpEncryptFlags flags
   3.761 +    );
   3.762 +
   3.763 +    HRESULT ReEvaluateMessageRating(
   3.764 +        [in] struct TextMessage *src,
   3.765 +        [in] SAFEARRAY(BSTR) x_KeyList, // referring to X-KeyList mail header
   3.766 +        [in] pEpRating x_EncStatus, // referring to X-EncStatus mail header
   3.767 +        [out, retval] pEpRating *rating
   3.768 +    );
   3.769 +
   3.770 +        HRESULT UndoLastMistrust();
   3.771 +};
   3.772 +
   3.773 +[
   3.774 +    uuid(564A4350-419E-47F1-B0DF-6FCCF0CD0BBC),
   3.775 +    version(1.0),
   3.776 +]
   3.777 +library pEpCOMServerAdapterLib
   3.778 +{
   3.779 +    importlib("stdole2.tlb");
   3.780 +
   3.781 +    [
   3.782 +        uuid(5FF6682B-727B-4DFE-A68D-28982874C0C7)
   3.783 +    ]
   3.784 +    coclass pEpEngine {
   3.785 +        [default] interface IpEpEngine2;
   3.786 +        interface IpEpEngine;
   3.787 +        interface IpEpEngineCallbacks2;
   3.788 +    };
   3.789 +};