CpEpEngine.cpp
author Markus Schaber <markus@pep-security.net>
Thu, 01 Sep 2016 19:09:52 +0200
branchoutlook_mime_support
changeset 155 0264d4b637a4
parent 150 316269fc987e
parent 151 432c35b5903c
child 156 8c9f8ce2c3a8
permissions -rw-r--r--
Merge with default
vb@0
     1
// CpEpEngine.cpp : Implementation of CpEpEngine
vb@0
     2
vb@0
     3
#include "stdafx.h"
vb@0
     4
#include "CpEpEngine.h"
vb@0
     5
vb@10
     6
using namespace std;
vb@10
     7
using namespace pEp::utility;
vb@0
     8
vb@0
     9
// CpEpEngine
vb@0
    10
vb@0
    11
STDMETHODIMP CpEpEngine::InterfaceSupportsErrorInfo(REFIID riid)
vb@0
    12
{
vb@0
    13
	static const IID* const arr[] = 
vb@0
    14
	{
vb@0
    15
		&IID_IpEpEngine
vb@0
    16
	};
vb@0
    17
vb@0
    18
	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
vb@0
    19
	{
vb@0
    20
		if (InlineIsEqualGUID(*arr[i],riid))
vb@0
    21
			return S_OK;
vb@0
    22
	}
vb@0
    23
	return S_FALSE;
vb@0
    24
}
vb@0
    25
vb@0
    26
#define FAIL(msg) error(msg)
vb@0
    27
vb@61
    28
STDMETHODIMP CpEpEngine::verbose_logging(VARIANT_BOOL enable)
vb@51
    29
{
vb@61
    30
    verbose_mode = enable != VARIANT_FALSE;
vb@60
    31
    return S_OK;
vb@60
    32
}
vb@60
    33
vb@61
    34
STDMETHODIMP CpEpEngine::passive_mode(VARIANT_BOOL enable)
vb@60
    35
{
vb@61
    36
    ::config_passive_mode(get_session(), enable != VARIANT_FALSE);
vb@60
    37
    return S_OK;
vb@60
    38
}
vb@60
    39
vb@61
    40
STDMETHODIMP CpEpEngine::unencrypted_subject(VARIANT_BOOL enable)
vb@60
    41
{
vb@61
    42
    ::config_unencrypted_subject(get_session(), enable != VARIANT_FALSE);
vb@51
    43
    return S_OK;
vb@51
    44
}
vb@0
    45
vb@0
    46
STDMETHODIMP CpEpEngine::log(BSTR title, BSTR entity, BSTR description, BSTR comment)
vb@0
    47
{
vb@0
    48
    string _title;
vb@0
    49
    string _entity;
vb@0
    50
    string _description;
vb@0
    51
    string _comment;
vb@0
    52
    HRESULT result = S_OK;
vb@0
    53
vb@0
    54
    assert(title);
vb@0
    55
    if (title)
vb@0
    56
        _title = utf8_string(title);
vb@0
    57
    else
vb@0
    58
        result = E_INVALIDARG;
vb@0
    59
vb@0
    60
    assert(entity);
vb@0
    61
    if (entity)
vb@0
    62
        _entity = utf8_string(entity);
vb@0
    63
    else
vb@0
    64
        result = E_INVALIDARG;
vb@0
    65
vb@0
    66
    if (description)
vb@0
    67
        _description = utf8_string(description);
vb@0
    68
vb@0
    69
    if (comment)
vb@0
    70
        _comment = utf8_string(comment);
vb@0
    71
vb@0
    72
    if (result != S_OK)
vb@0
    73
        return result;
vb@0
    74
vb@0
    75
    PEP_STATUS _status = ::log_event(get_session(), _title.c_str(), _entity.c_str(), _description.c_str(), _comment.c_str());
vb@0
    76
    assert(_status == PEP_STATUS_OK);
vb@0
    77
    if (_status != PEP_STATUS_OK)
vb@0
    78
        return FAIL(L"log_event");
vb@0
    79
    else
vb@0
    80
        return S_OK;
vb@0
    81
}
vb@0
    82
vb@0
    83
vb@0
    84
STDMETHODIMP CpEpEngine::decrypt(BSTR ctext, BSTR * ptext, LPSAFEARRAY * key_list, pEp_STATUS * status)
vb@0
    85
{
vb@0
    86
    assert(ctext);
vb@0
    87
    assert(ptext);
vb@0
    88
    assert(key_list);
vb@0
    89
    assert(status);
vb@0
    90
vb@0
    91
    if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
vb@0
    92
        if (ptext)
vb@0
    93
            *ptext = NULL;
vb@0
    94
        if (key_list)
vb@0
    95
            *key_list = NULL;
vb@0
    96
        if (status)
vb@0
    97
            *status = pEp_UNENCRYPTED;
vb@0
    98
        return E_INVALIDARG;
vb@0
    99
    }
vb@0
   100
vb@0
   101
    string _ctext = utf8_string(ctext);
vb@0
   102
vb@0
   103
    char *_ptext = NULL;
vb@0
   104
    size_t _psize = 0;
vb@0
   105
    ::stringlist_t *_keylist = NULL;
vb@0
   106
    PEP_STATUS _status;
vb@0
   107
vb@0
   108
    _status = ::decrypt_and_verify(get_session(), _ctext.c_str(), _ctext.size(), &_ptext, &_psize, &_keylist);
vb@0
   109
    assert(_status != PEP_OUT_OF_MEMORY);
vb@0
   110
    if (_status == PEP_OUT_OF_MEMORY)
vb@0
   111
        return E_OUTOFMEMORY;
vb@0
   112
vb@0
   113
    *status = (pEp_STATUS) _status;
vb@0
   114
    if (_ptext == NULL) {
vb@0
   115
        if (_keylist) {
vb@0
   116
            string msg;
vb@0
   117
            if (_keylist->value[0] != 0) {
vb@0
   118
                msg = _keylist->value;
vb@0
   119
            }
vb@0
   120
            else {
vb@0
   121
                for (::stringlist_t *s = _keylist->next; s != NULL; s = s->next) {
vb@0
   122
                    if (s->value) {
vb@0
   123
                        msg += s->value;
vb@0
   124
                        msg += ";";
vb@0
   125
                    }
vb@0
   126
                }
vb@0
   127
            }
vb@0
   128
            ::free_stringlist(_keylist);
vb@0
   129
vb@0
   130
            return FAIL(utf16_bstr(msg));
vb@0
   131
        }
vb@0
   132
        else
vb@0
   133
            return FAIL(L"cannot decrypt");
vb@0
   134
    }
vb@0
   135
vb@40
   136
    *ptext = utf16_bstr(_ptext);
vb@0
   137
    pEp_free(_ptext);
vb@0
   138
vb@0
   139
    if (_keylist && _keylist->value)
vb@40
   140
        *key_list = string_array(_keylist);
vb@0
   141
    else
vb@0
   142
        *key_list = NULL;
vb@0
   143
    ::free_stringlist(_keylist);
vb@0
   144
vb@0
   145
    return S_OK;
vb@0
   146
}
vb@0
   147
vb@0
   148
STDMETHODIMP CpEpEngine::decrypt_b(BSTR ctext, LPSAFEARRAY * ptext, LPSAFEARRAY * key_list, pEp_STATUS * status)
vb@0
   149
{
vb@0
   150
    assert(ctext);
vb@0
   151
    assert(ptext);
vb@0
   152
    assert(key_list);
vb@0
   153
    assert(status);
vb@0
   154
vb@0
   155
    if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
vb@0
   156
        if (ptext)
vb@0
   157
            *ptext = NULL;
vb@0
   158
        if (key_list)
vb@0
   159
            *key_list = NULL;
vb@0
   160
        if (status)
vb@0
   161
            *status = pEp_UNENCRYPTED;
vb@0
   162
        return E_INVALIDARG;
vb@0
   163
    }
vb@0
   164
vb@0
   165
    // Welcome to Windoze string hell!
vb@0
   166
vb@0
   167
    char *_ctext = NULL;
vb@0
   168
    _bstr_t bstr_ctext(ctext, true);
vb@0
   169
    int w_csize = bstr_ctext.length() + 1;
vb@0
   170
    int _csize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, (wchar_t *) bstr_ctext, w_csize, NULL, 0, NULL, NULL);
vb@0
   171
    if (_csize) {
vb@0
   172
        _ctext = new char[_csize];
vb@0
   173
        WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, (wchar_t *) bstr_ctext, w_csize, _ctext, _csize, NULL, NULL);
vb@0
   174
    }
vb@0
   175
vb@0
   176
    char *_ptext = NULL;
vb@0
   177
    size_t _psize = 0;
vb@0
   178
    ::stringlist_t *_keylist = NULL;
vb@0
   179
    PEP_STATUS _status;
vb@0
   180
vb@0
   181
    _status = ::decrypt_and_verify(get_session(), _ctext, _csize, &_ptext, &_psize, &_keylist);
vb@0
   182
    assert(_status != PEP_OUT_OF_MEMORY);
vb@0
   183
    delete[] _ctext;
vb@0
   184
    if (_status == PEP_OUT_OF_MEMORY) {
vb@0
   185
        ::free_stringlist(_keylist);
vb@0
   186
        return E_OUTOFMEMORY;
vb@0
   187
    }
vb@0
   188
    *status = (pEp_STATUS) _status;
vb@0
   189
vb@0
   190
    if (_ptext == NULL) {
vb@0
   191
        ::free_stringlist(_keylist);
vb@0
   192
        return FAIL(L"decrypt_and_verify");
vb@0
   193
    }
vb@0
   194
vb@0
   195
    CComSafeArray<BYTE> sa_ptext;
vb@0
   196
vb@0
   197
    HRESULT _result = sa_ptext.Create(_psize, 0);
vb@0
   198
    assert(_result == S_OK);
vb@0
   199
    if (_result == E_OUTOFMEMORY) {
vb@0
   200
        pEp_free(_ptext);
vb@0
   201
        ::free_stringlist(_keylist);
vb@0
   202
        return E_OUTOFMEMORY;
vb@0
   203
    }
vb@0
   204
    else if (_result != S_OK) {
vb@0
   205
        pEp_free(_ptext);
vb@0
   206
        ::free_stringlist(_keylist);
vb@0
   207
        return FAIL(L"CComSafeArray<BYTE>::Create");
vb@0
   208
    }
vb@0
   209
vb@0
   210
    memcpy(sa_ptext.m_psa->pvData, _ptext, _psize);
vb@0
   211
    *ptext = sa_ptext.Detach();
vb@0
   212
    ::pEp_free(_ptext);
vb@0
   213
vb@0
   214
    if (_keylist && _keylist->value)
vb@40
   215
        *key_list = string_array(_keylist);
vb@0
   216
    else
vb@0
   217
        *key_list = NULL;
vb@0
   218
    ::free_stringlist(_keylist);
vb@0
   219
vb@0
   220
    return S_OK;
vb@0
   221
}
vb@0
   222
vb@0
   223
STDMETHODIMP CpEpEngine::verify(BSTR text, BSTR signature, LPSAFEARRAY * key_list, pEp_STATUS * verify_status)
vb@0
   224
{
vb@0
   225
    assert(text);
vb@0
   226
    assert(signature);
vb@0
   227
    assert(key_list);
vb@0
   228
vb@0
   229
    if (text == NULL || signature == NULL || key_list == NULL)
vb@0
   230
        return E_INVALIDARG;
vb@0
   231
vb@0
   232
    string _text = utf8_string(text);
vb@0
   233
    string _signature = utf8_string(signature);
vb@0
   234
vb@0
   235
    ::stringlist_t *_keylist = NULL;
vb@0
   236
    PEP_STATUS _status;
vb@0
   237
    _status = ::verify_text(get_session(), _text.c_str(), _text.size(), _signature.c_str(), _signature.size(), &_keylist);
vb@0
   238
    assert(_status != PEP_OUT_OF_MEMORY);
vb@0
   239
    if (_status == PEP_OUT_OF_MEMORY)
vb@0
   240
        return E_OUTOFMEMORY;
vb@0
   241
    if (_status == PEP_DECRYPT_WRONG_FORMAT || _status == PEP_UNKNOWN_ERROR)
vb@0
   242
        return FAIL(L"verify_text");
vb@0
   243
vb@0
   244
    *verify_status = (pEp_STATUS) _status;
vb@0
   245
vb@0
   246
    if (_keylist && _keylist->value)
vb@40
   247
        *key_list = string_array(_keylist);
vb@0
   248
    else
vb@0
   249
        *key_list = NULL;
vb@0
   250
    ::free_stringlist(_keylist);
vb@0
   251
vb@0
   252
    return S_OK;
vb@0
   253
}
vb@0
   254
vb@0
   255
STDMETHODIMP CpEpEngine::encrypt(SAFEARRAY * key_list, BSTR ptext, BSTR * ctext, pEp_STATUS * status)
vb@0
   256
{
vb@0
   257
    assert(key_list);
vb@0
   258
    assert(ptext);
vb@0
   259
    assert(ctext);
vb@0
   260
    assert(status);
vb@0
   261
vb@0
   262
    if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
vb@0
   263
        if (ctext)
vb@0
   264
            *ctext = NULL;
vb@0
   265
        if (status)
vb@0
   266
            *status = pEp_UNKNOWN_ERROR;
vb@0
   267
        return E_INVALIDARG;
vb@0
   268
    }
vb@0
   269
vb@0
   270
    HRESULT result = S_OK;
vb@0
   271
vb@0
   272
    ::stringlist_t *_keylist = new_stringlist(key_list);
vb@0
   273
    string _ptext = utf8_string(ptext);
vb@0
   274
vb@0
   275
    char *_ctext = NULL;
vb@0
   276
    size_t _csize = 0;
vb@0
   277
    PEP_STATUS _status;
vb@0
   278
vb@0
   279
    _status = ::encrypt_and_sign(get_session(), _keylist, _ptext.c_str(), _ptext.size(), &_ctext, &_csize);
vb@0
   280
vb@0
   281
    assert(_status != PEP_OUT_OF_MEMORY);
vb@0
   282
    ::free_stringlist(_keylist);
vb@0
   283
    if (_status == PEP_OUT_OF_MEMORY)
vb@0
   284
        return E_OUTOFMEMORY;
vb@0
   285
    *status = (pEp_STATUS) _status;
vb@0
   286
vb@0
   287
    if (_ctext == NULL)
vb@0
   288
        return FAIL(L"encrypt_and_sign");
vb@0
   289
vb@40
   290
    *ctext = utf16_bstr(_ctext);
vb@0
   291
    pEp_free(_ctext);
vb@0
   292
vb@0
   293
    return S_OK;
vb@0
   294
}
vb@0
   295
vb@0
   296
STDMETHODIMP CpEpEngine::encrypt_b(SAFEARRAY * key_list, SAFEARRAY * ptext, BSTR * ctext, pEp_STATUS * status)
vb@0
   297
{
vb@0
   298
    assert(key_list);
vb@0
   299
    assert(ptext);
vb@0
   300
    assert(ctext);
vb@0
   301
    assert(status);
vb@0
   302
vb@0
   303
    if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
vb@0
   304
        if (ctext)
vb@0
   305
            *ctext = NULL;
vb@0
   306
        if (status)
vb@0
   307
            *status = pEp_UNKNOWN_ERROR;
vb@0
   308
        return E_INVALIDARG;
vb@0
   309
    }
vb@0
   310
vb@0
   311
    HRESULT result = S_OK;
vb@0
   312
vb@0
   313
    ::stringlist_t *_keylist = new_stringlist(key_list);
vb@0
   314
vb@0
   315
    char *_ctext = NULL;
vb@0
   316
    size_t _csize = 0;
vb@0
   317
    ::PEP_STATUS _status;
vb@0
   318
vb@0
   319
    _status = ::encrypt_and_sign(get_session(), _keylist, (const char *) ptext->pvData, ptext->rgsabound[0].cElements, &_ctext, &_csize);
vb@0
   320
    assert(_status != PEP_OUT_OF_MEMORY);
vb@0
   321
    ::free_stringlist(_keylist);
vb@0
   322
    if (_status == PEP_OUT_OF_MEMORY)
vb@0
   323
        return E_OUTOFMEMORY;
vb@0
   324
    *status = (pEp_STATUS) _status;
vb@0
   325
vb@0
   326
    if (_ctext == NULL)
vb@0
   327
        return FAIL(L"encrypt_and_sign");
vb@0
   328
vb@0
   329
    *status = (pEp_STATUS) _status;
vb@0
   330
    wchar_t *w_ctext = NULL;
vb@0
   331
    int w_csize = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _ctext, _csize, NULL, 0);
vb@0
   332
    if (w_csize) {
vb@0
   333
        w_ctext = new wchar_t[w_csize + 1];
vb@0
   334
        MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _ctext, _csize, w_ctext, w_csize);
vb@0
   335
        w_ctext[w_csize] = 0; // this is for debugging; Visual Studio will crash without that if you're unlucky
vb@0
   336
    }
vb@0
   337
    *ctext = ::SysAllocStringLen(w_ctext, w_csize);
vb@0
   338
    assert(ctext);
vb@0
   339
    delete[] w_ctext;
vb@0
   340
    pEp_free(_ctext);
vb@0
   341
    if (ctext == NULL)
vb@0
   342
        return E_OUTOFMEMORY;
vb@0
   343
vb@0
   344
    return S_OK;
vb@0
   345
}
vb@0
   346
vb@17
   347
STDMETHODIMP CpEpEngine::trustword(LONG value, BSTR lang, BSTR * word)
vb@0
   348
{
vb@0
   349
    assert(value >= 0 && value <= 65535);
vb@0
   350
    assert(word);
vb@0
   351
vb@0
   352
    HRESULT result = S_OK;
vb@0
   353
vb@0
   354
    uint16_t _value = 0;
vb@0
   355
    if (value < 0 || value > 65535)
vb@0
   356
        result = E_INVALIDARG;
vb@0
   357
    else
vb@0
   358
        _value = (uint16_t) value;
vb@0
   359
vb@0
   360
    string _lang = "en";
vb@0
   361
    if (lang) {
vb@0
   362
        _lang = utf8_string(lang);
vb@0
   363
        if (_lang.length() != 2)
vb@0
   364
            result = E_INVALIDARG;
vb@0
   365
    }
vb@0
   366
vb@0
   367
    if (word == NULL)
vb@0
   368
        result = E_INVALIDARG;
vb@0
   369
vb@0
   370
    if (result != S_OK)
vb@0
   371
        return result;
vb@0
   372
vb@0
   373
    char *_word = NULL;
vb@0
   374
    size_t _wsize = 0;
vb@0
   375
vb@17
   376
    PEP_STATUS status = ::trustword(get_session(), _value, _lang.c_str(), &_word, &_wsize);
vb@0
   377
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   378
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   379
        return E_OUTOFMEMORY;
vb@0
   380
vb@0
   381
    if (_word == NULL) {
vb@0
   382
        *word = NULL;
vb@17
   383
        return FAIL(L"trustword");
vb@0
   384
    }
vb@0
   385
    else {
vb@40
   386
        *word = utf16_bstr(_word);
vb@0
   387
        pEp_free(_word);
vb@0
   388
        return S_OK;
vb@0
   389
    }
vb@0
   390
}
vb@0
   391
vb@17
   392
STDMETHODIMP CpEpEngine::trustwords(BSTR fpr, BSTR lang, LONG max_words, BSTR * words)
vb@0
   393
{
vb@0
   394
    assert(fpr);
vb@0
   395
    assert(max_words >= 0);
vb@0
   396
    assert(words);
vb@0
   397
vb@0
   398
    HRESULT result = S_OK;
vb@0
   399
vb@0
   400
    string _fpr;
vb@0
   401
    if (fpr)
vb@0
   402
        _fpr = utf8_string(fpr);
vb@0
   403
    else
vb@0
   404
        result = E_INVALIDARG;
vb@0
   405
vb@0
   406
    string _lang;
vb@0
   407
    if (lang) {
vb@0
   408
        _lang = utf8_string(lang);
vb@0
   409
        if (_lang.length()) {
vb@0
   410
            if (_lang.length() != 2)
vb@0
   411
                result = E_INVALIDARG;
vb@0
   412
        }
vb@0
   413
        else
vb@0
   414
            _lang = "en";
vb@0
   415
    }
vb@0
   416
    else
vb@0
   417
        _lang = "en";
vb@0
   418
vb@0
   419
    if (max_words < 0)
vb@0
   420
        result = E_INVALIDARG;
vb@0
   421
vb@0
   422
    if (words == NULL)
vb@0
   423
        result = E_INVALIDARG;
vb@0
   424
vb@0
   425
    if (result != S_OK)
vb@0
   426
        return result;
vb@0
   427
vb@0
   428
    char *_words = NULL;
vb@0
   429
    size_t _wsize = 0;
vb@0
   430
vb@17
   431
    PEP_STATUS status = ::trustwords(get_session(), _fpr.c_str(), _lang.c_str(), &_words, &_wsize, max_words);
vb@0
   432
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   433
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   434
        return E_OUTOFMEMORY;
vb@0
   435
vb@0
   436
    if (_words == NULL) {
vb@0
   437
        *words = NULL;
vb@17
   438
        return FAIL(L"trustwords");
vb@0
   439
    }
vb@0
   440
    else {
vb@40
   441
        *words = utf16_bstr(_words);
vb@0
   442
        pEp_free(_words);
vb@0
   443
        return S_OK;
vb@0
   444
    }
vb@0
   445
}
vb@0
   446
vb@57
   447
STDMETHODIMP CpEpEngine::get_crashdump_log(LONG maxlines, BSTR * log)
vb@57
   448
{
vb@57
   449
    assert(maxlines >= 0);
vb@57
   450
    assert(log);
vb@57
   451
vb@57
   452
    if (!(maxlines >= 0 && log))
vb@57
   453
        return E_INVALIDARG;
vb@57
   454
vb@57
   455
    char *_log;
vb@57
   456
    PEP_STATUS status = ::get_crashdump_log(get_session(), (int) maxlines, &_log);
vb@57
   457
    assert(status == PEP_STATUS_OK);
vb@57
   458
    if (status == PEP_OUT_OF_MEMORY)
vb@57
   459
        return E_OUTOFMEMORY;
vb@57
   460
    if (status != PEP_STATUS_OK || _log == NULL)
vb@57
   461
        return FAIL(L"get_crashdump_log");
vb@57
   462
vb@57
   463
    *log = utf16_bstr(_log);
vb@57
   464
    pEp_free(_log);
vb@57
   465
    return S_OK;
vb@57
   466
}
vb@57
   467
Dean@151
   468
STDMETHODIMP CpEpEngine::get_engine_version(BSTR * engine_version)
Dean@151
   469
{
Dean@151
   470
    assert(engine_version);
Dean@151
   471
Dean@151
   472
    if (!engine_version)
Dean@151
   473
        return E_INVALIDARG;
Dean@151
   474
Dean@151
   475
    const char *_enginge_version = ::get_engine_version();
Dean@151
   476
Dean@151
   477
    if (_enginge_version == NULL)
Dean@151
   478
        return FAIL(L"get_engine_version");
Dean@151
   479
Dean@151
   480
    *engine_version = utf16_bstr(_enginge_version);
Dean@151
   481
Dean@151
   482
    return S_OK;
Dean@151
   483
}
Dean@151
   484
vb@59
   485
STDMETHODIMP CpEpEngine::get_languagelist(BSTR * languages)
vb@59
   486
{
vb@59
   487
    assert(languages);
vb@59
   488
vb@59
   489
    if (!languages)
vb@59
   490
        return E_INVALIDARG;
vb@59
   491
vb@59
   492
    char *_languages;
vb@59
   493
    PEP_STATUS status = ::get_languagelist(get_session(), &_languages);
vb@59
   494
    assert(status == PEP_STATUS_OK);
vb@59
   495
    if (status == PEP_OUT_OF_MEMORY)
vb@59
   496
        return E_OUTOFMEMORY;
vb@59
   497
    if (status != PEP_STATUS_OK || _languages == NULL)
vb@59
   498
        return FAIL(L"get_languagelist");
vb@59
   499
vb@59
   500
    *languages = utf16_bstr(_languages);
vb@59
   501
    pEp_free(_languages);
vb@59
   502
    return S_OK;
vb@59
   503
}
vb@59
   504
vb@59
   505
STDMETHODIMP CpEpEngine::get_phrase(BSTR lang, LONG phrase_id, BSTR * phrase)
vb@59
   506
{
vb@59
   507
    assert(lang && phrase_id >= 0 && phrase);
vb@59
   508
vb@59
   509
    if (!(lang && phrase_id >= 0 && phrase))
vb@59
   510
        return E_INVALIDARG;
vb@59
   511
vb@59
   512
    string _lang = utf8_string(lang);
vb@59
   513
    assert(_lang.length() == 2);
vb@59
   514
    if (_lang.length() != 2)
vb@59
   515
        return E_INVALIDARG;
vb@59
   516
vb@59
   517
    char *_phrase;
vb@59
   518
    PEP_STATUS status = ::get_phrase(get_session(), _lang.c_str(), (int) phrase_id, &_phrase);
vb@59
   519
    assert(status == PEP_STATUS_OK);
vb@59
   520
    if (status == PEP_OUT_OF_MEMORY)
vb@59
   521
        return E_OUTOFMEMORY;
vb@59
   522
    if (status != PEP_STATUS_OK || _phrase == NULL)
vb@59
   523
        return FAIL(L"get_phrase");
vb@59
   524
vb@59
   525
    *phrase = utf16_bstr(_phrase);
vb@59
   526
    pEp_free(_phrase);
vb@59
   527
    return S_OK;
vb@59
   528
}
vb@59
   529
vb@70
   530
STDMETHODIMP CpEpEngine::get_identity(BSTR address, BSTR user_id, pEp_identity_s * ident)
vb@0
   531
{
vb@0
   532
    assert(address);
vb@70
   533
    assert(user_id);
vb@0
   534
    assert(ident);
vb@0
   535
vb@0
   536
    if (address == NULL)
vb@0
   537
        return E_INVALIDARG;
vb@70
   538
    if (user_id == NULL)
vb@70
   539
        return E_INVALIDARG;
vb@0
   540
    if (ident == NULL)
vb@0
   541
        return E_INVALIDARG;
vb@0
   542
vb@0
   543
    string _address = utf8_string(address);
vb@70
   544
    string _user_id = utf8_string(user_id);
vb@70
   545
vb@0
   546
    ::pEp_identity *_ident = NULL;
vb@70
   547
    PEP_STATUS status = ::get_identity(get_session(), _address.c_str(), _user_id.c_str(), &_ident);
vb@0
   548
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   549
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   550
        return E_OUTOFMEMORY;
vb@0
   551
vb@0
   552
    if (_ident == NULL) {
vb@0
   553
        return FAIL(L"get_identity");
vb@0
   554
    }
vb@0
   555
vb@0
   556
    copy_identity(ident, _ident);
vb@0
   557
    ::free_identity(_ident);
vb@0
   558
vb@0
   559
    return S_OK;
vb@0
   560
}
vb@0
   561
vb@0
   562
STDMETHODIMP CpEpEngine::set_identity(pEp_identity_s * ident)
vb@0
   563
{
vb@0
   564
    assert(ident);
vb@0
   565
    assert(ident->address);
vb@0
   566
    assert(ident->fpr);
vb@0
   567
    assert(ident->username);
vb@0
   568
    assert(ident->user_id);
vb@0
   569
vb@0
   570
    if (ident == NULL || ident->address == NULL || ident->fpr == NULL
vb@0
   571
        || ident->username == NULL || ident->user_id == NULL)
vb@0
   572
        return E_INVALIDARG;
vb@0
   573
vb@0
   574
    ::pEp_identity *_ident = new_identity(ident);
vb@0
   575
    ::PEP_STATUS status = ::set_identity(get_session(), _ident);
vb@0
   576
    ::free_identity(_ident);
vb@0
   577
vb@0
   578
    if (status != ::PEP_STATUS_OK)
vb@0
   579
        return FAIL(L"set_identity");
vb@0
   580
    else
vb@0
   581
        return S_OK;
vb@0
   582
}
vb@0
   583
vb@0
   584
STDMETHODIMP CpEpEngine::generate_keypair(pEp_identity_s * ident, BSTR * fpr)
vb@0
   585
{
vb@0
   586
    assert(ident);
vb@0
   587
    assert(ident->address);
vb@0
   588
    assert(ident->username);
vb@0
   589
    assert(fpr);
vb@0
   590
vb@0
   591
    if (ident == NULL || ident->address == NULL || ident->username == NULL || fpr == NULL)
vb@0
   592
        return E_INVALIDARG;
vb@0
   593
vb@0
   594
    ::pEp_identity *_ident = new_identity(ident);
vb@0
   595
    ::pEp_free(_ident->fpr);
vb@0
   596
    _ident->fpr = NULL;
vb@0
   597
vb@0
   598
    ::PEP_STATUS status = ::generate_keypair(get_session(), _ident);
vb@0
   599
    assert(status != ::PEP_OUT_OF_MEMORY);
vb@0
   600
    if (status == ::PEP_OUT_OF_MEMORY) {
vb@0
   601
        ::free_identity(_ident);
vb@0
   602
        return E_OUTOFMEMORY;
vb@0
   603
    }
vb@0
   604
vb@0
   605
    if (_ident->fpr)
vb@40
   606
        *fpr = utf16_bstr(_ident->fpr);
vb@0
   607
vb@0
   608
    ::free_identity(_ident);
vb@0
   609
vb@0
   610
    if (status != ::PEP_STATUS_OK)
vb@0
   611
        return FAIL(L"generate_keypair");
vb@0
   612
vb@0
   613
    return S_OK;
vb@0
   614
}
vb@0
   615
vb@0
   616
STDMETHODIMP CpEpEngine::delete_keypair(BSTR fpr)
vb@0
   617
{
vb@0
   618
    assert(fpr);
vb@0
   619
vb@0
   620
    if (fpr == NULL)
vb@0
   621
        return E_INVALIDARG;
vb@0
   622
vb@0
   623
    string _fpr = utf8_string(fpr);
vb@0
   624
vb@0
   625
    ::PEP_STATUS status = ::delete_keypair(get_session(), _fpr.c_str());
vb@0
   626
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   627
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   628
        return E_OUTOFMEMORY;
vb@0
   629
vb@0
   630
    if (status != ::PEP_STATUS_OK)
vb@0
   631
        return FAIL(L"delete_keypair");
vb@0
   632
    else
vb@0
   633
        return S_OK;
vb@0
   634
}
vb@0
   635
vb@0
   636
STDMETHODIMP CpEpEngine::import_key(BSTR key_data)
vb@0
   637
{
vb@0
   638
    assert(key_data);
vb@0
   639
vb@0
   640
    if (key_data == NULL)
vb@0
   641
        return E_INVALIDARG;
vb@0
   642
vb@0
   643
    string _key_data = utf8_string(key_data);
vb@0
   644
Edouard@106
   645
    PEP_STATUS status = ::import_key(get_session(), _key_data.c_str(), _key_data.length(), NULL);
vb@0
   646
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   647
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   648
        return E_OUTOFMEMORY;
vb@0
   649
vb@0
   650
    if (status != pEp_STATUS_OK)
vb@0
   651
        return FAIL(L"import_key");
vb@0
   652
    else
vb@0
   653
        return S_OK;
vb@0
   654
}
vb@0
   655
vb@0
   656
STDMETHODIMP CpEpEngine::import_key_b(SAFEARRAY * key_data)
vb@0
   657
{
vb@0
   658
    assert(key_data);
vb@0
   659
vb@0
   660
    if (key_data == NULL)
vb@0
   661
        return E_INVALIDARG;
vb@0
   662
Edouard@106
   663
    ::PEP_STATUS status = ::import_key(get_session(), (const char *) key_data->pvData, key_data->rgsabound[0].cElements, NULL);
vb@0
   664
    assert(status != ::PEP_OUT_OF_MEMORY);
vb@0
   665
    if (status == ::PEP_OUT_OF_MEMORY)
vb@0
   666
        return E_OUTOFMEMORY;
vb@0
   667
vb@0
   668
    if (status != ::PEP_STATUS_OK)
vb@0
   669
        return FAIL(L"import_key");
vb@0
   670
    else
vb@0
   671
        return S_OK;
vb@0
   672
}
vb@0
   673
vb@0
   674
STDMETHODIMP CpEpEngine::export_key(BSTR fpr, BSTR * key_data)
vb@0
   675
{
vb@0
   676
    assert(fpr);
vb@0
   677
    assert(key_data);
vb@0
   678
vb@0
   679
    if (fpr == NULL || key_data == NULL)
vb@0
   680
        return E_INVALIDARG;
vb@0
   681
vb@0
   682
    string _fpr = utf8_string(fpr);
vb@0
   683
    char *_key_data = NULL;
vb@0
   684
    size_t _size = 0;
vb@0
   685
vb@0
   686
    ::PEP_STATUS status = ::export_key(get_session(), _fpr.c_str(), &_key_data, &_size);
vb@0
   687
    assert(status != ::PEP_OUT_OF_MEMORY);
vb@0
   688
    if (status == ::PEP_OUT_OF_MEMORY)
vb@0
   689
        return E_OUTOFMEMORY;
vb@0
   690
vb@0
   691
    if (status != ::PEP_STATUS_OK)
vb@0
   692
        return FAIL(L"export_key");
vb@0
   693
vb@0
   694
    _bstr_t b_key_data(utf16_string(_key_data).c_str());
vb@0
   695
    pEp_free(_key_data);
vb@0
   696
    *key_data = b_key_data.Detach();
vb@0
   697
vb@0
   698
    return S_OK;
vb@0
   699
}
vb@0
   700
vb@0
   701
STDMETHODIMP CpEpEngine::recv_key(BSTR pattern)
vb@0
   702
{
vb@0
   703
    assert(pattern);
vb@0
   704
vb@0
   705
    if (pattern == NULL)
vb@0
   706
        return E_INVALIDARG;
vb@0
   707
vb@0
   708
    string _pattern = utf8_string(pattern);
vb@0
   709
vb@0
   710
    PEP_STATUS status = ::recv_key(get_session(), _pattern.c_str());
vb@0
   711
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   712
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   713
        return E_OUTOFMEMORY;
vb@0
   714
vb@0
   715
    if (status != ::PEP_STATUS_OK)
vb@0
   716
        return FAIL(L"recv_key");
vb@0
   717
    else
vb@0
   718
        return S_OK;
vb@0
   719
}
vb@0
   720
vb@0
   721
STDMETHODIMP CpEpEngine::find_keys(BSTR pattern, LPSAFEARRAY * key_list)
vb@0
   722
{
vb@0
   723
    assert(pattern);
vb@0
   724
    assert(key_list);
vb@0
   725
vb@0
   726
    if (pattern == NULL || key_list == NULL)
vb@0
   727
        return E_INVALIDARG;
vb@0
   728
vb@0
   729
    string _pattern = utf8_string(pattern);
vb@0
   730
    ::stringlist_t *_keylist = NULL;
vb@0
   731
vb@0
   732
    PEP_STATUS status = ::find_keys(get_session(), _pattern.c_str(), &_keylist);
vb@0
   733
    assert(status != PEP_OUT_OF_MEMORY);
vb@0
   734
    if (status == PEP_OUT_OF_MEMORY)
vb@0
   735
        return E_OUTOFMEMORY;
vb@0
   736
vb@0
   737
    if (status != ::PEP_STATUS_OK)
vb@0
   738
        return FAIL(L"find_keys");
vb@0
   739
vb@0
   740
    if (_keylist && _keylist->value) {
vb@40
   741
        *key_list = string_array(_keylist);
vb@0
   742
    }
vb@0
   743
    else {
vb@0
   744
        ::free_stringlist(_keylist);
vb@0
   745
        return FAIL(L"find_keys: no keys found");
vb@0
   746
    }
vb@0
   747
vb@0
   748
    ::free_stringlist(_keylist);
vb@0
   749
    return S_OK;
vb@0
   750
}
vb@0
   751
vb@0
   752
STDMETHODIMP CpEpEngine::send_key(BSTR pattern)
vb@0
   753
{
vb@0
   754
    assert(pattern);
vb@0
   755
vb@0
   756
    if (pattern == NULL)
vb@0
   757
        return E_INVALIDARG;
vb@0
   758
vb@0
   759
    string _pattern = utf8_string(pattern);
vb@0
   760
vb@0
   761
    ::PEP_STATUS status = ::send_key(get_session(), _pattern.c_str());
vb@0
   762
vb@0
   763
    if (status != ::PEP_STATUS_OK)
vb@0
   764
        return FAIL(L"send_key");
vb@0
   765
    else
vb@0
   766
        return S_OK;
vb@0
   767
}
vb@0
   768
vb@24
   769
STDMETHODIMP CpEpEngine::start_keyserver_lookup()
vb@24
   770
{
vb@27
   771
    if (identity_queue.load())
vb@24
   772
        return S_OK;
vb@24
   773
vb@27
   774
    identity_queue.store(new identity_queue_t());
vb@25
   775
    keymanagement_thread = new thread(::do_keymanagement, retrieve_next_identity, (void *) identity_queue.load());
vb@25
   776
    
vb@24
   777
    return S_OK;
vb@24
   778
}
vb@24
   779
vb@24
   780
STDMETHODIMP CpEpEngine::stop_keyserver_lookup()
vb@24
   781
{
vb@27
   782
    if (identity_queue.load() == NULL)
vb@24
   783
        return S_OK;
vb@24
   784
vb@25
   785
    identity_queue_t *_iq = identity_queue.load();
vb@27
   786
    identity_queue.store(NULL);
vb@25
   787
vb@24
   788
    pEp_identity_cpp shutdown;
vb@25
   789
    _iq->push_front(shutdown);
vb@24
   790
vb@24
   791
    keymanagement_thread->join();
vb@24
   792
    delete keymanagement_thread;
vb@24
   793
    keymanagement_thread = NULL;
vb@24
   794
vb@25
   795
    delete _iq;
vb@24
   796
vb@24
   797
    return S_OK;
vb@24
   798
}
vb@24
   799
vb@0
   800
STDMETHODIMP CpEpEngine::examine_identity(pEp_identity_s * ident)
vb@0
   801
{
vb@0
   802
    assert(ident);
vb@0
   803
    if (ident == NULL)
vb@0
   804
        return E_INVALIDARG;
vb@0
   805
vb@25
   806
    if (identity_queue.load() == NULL) {
vb@24
   807
        try {
vb@25
   808
            identity_queue.load()->push_back(ident);
vb@24
   809
        }
vb@24
   810
        catch (bad_alloc) {
vb@24
   811
            return E_OUTOFMEMORY;
vb@24
   812
        }
vb@0
   813
    }
vb@0
   814
vb@0
   815
    return S_OK;
vb@0
   816
}
vb@0
   817
vb@0
   818
STDMETHODIMP CpEpEngine::myself(struct pEp_identity_s *ident, struct pEp_identity_s *result)
vb@0
   819
{
vb@0
   820
    assert(ident);
vb@0
   821
    assert(result);
vb@0
   822
vb@0
   823
    if (ident == NULL || result == NULL)
vb@0
   824
        return E_INVALIDARG;
vb@0
   825
vb@0
   826
    ::pEp_identity *_ident = new_identity(ident);
vb@0
   827
    assert(_ident);
vb@0
   828
    if (_ident == NULL)
vb@0
   829
        return E_OUTOFMEMORY;
vb@0
   830
markus@84
   831
	// DEBUG CODE - REMOVE BEFORE RELEASE!
markus@85
   832
	// sync_handshake_result_s handshakeResult;
markus@84
   833
	//
markus@85
   834
	// HRESULT res = Fire_ShowHandshake(ident, result, &handshakeResult);
markus@85
   835
	// 
markus@85
   836
	// HRESULT res2 = Fire_TestEvent(15, _bstr_t( "hallo"));
markus@84
   837
vb@0
   838
    PEP_STATUS status = ::myself(get_session(), _ident);
vb@0
   839
vb@0
   840
    if (status == PEP_STATUS_OK) {
vb@0
   841
        assert(_ident->fpr);
vb@0
   842
        copy_identity(result, _ident);
vb@0
   843
        ::free_identity(_ident);
vb@0
   844
        return S_OK;
vb@0
   845
    }
vb@0
   846
    else {
vb@0
   847
        ::free_identity(_ident);
vb@0
   848
        if (status == PEP_OUT_OF_MEMORY)
vb@0
   849
            return E_OUTOFMEMORY;
vb@0
   850
        else
vb@0
   851
            return FAIL(L"myself");
vb@0
   852
    }
vb@0
   853
}
vb@0
   854
vb@0
   855
STDMETHODIMP CpEpEngine::update_identity(struct pEp_identity_s *ident, struct pEp_identity_s *result)
vb@0
   856
{
vb@0
   857
    assert(ident);
vb@0
   858
    assert(result);
vb@0
   859
vb@0
   860
    if (ident == NULL || result == NULL)
vb@0
   861
        return E_INVALIDARG;
vb@0
   862
vb@0
   863
    ::pEp_identity *_ident = new_identity(ident);
vb@0
   864
    assert(_ident);
vb@0
   865
    if (_ident == NULL)
vb@0
   866
        return E_OUTOFMEMORY;
vb@0
   867
vb@0
   868
    PEP_STATUS status = ::update_identity(get_session(), _ident);
vb@0
   869
vb@0
   870
    if (status == PEP_STATUS_OK) {
vb@0
   871
        assert(_ident->fpr);
vb@0
   872
        copy_identity(result, _ident);
vb@0
   873
        ::free_identity(_ident);
vb@0
   874
        return S_OK;
vb@0
   875
    }
vb@0
   876
    else {
vb@0
   877
        ::free_identity(_ident);
vb@0
   878
        if (status == PEP_OUT_OF_MEMORY)
vb@0
   879
            return E_OUTOFMEMORY;
vb@0
   880
        else
vb@0
   881
            return FAIL(L"update_identity");
vb@0
   882
    }
vb@0
   883
}
vb@0
   884
vb@49
   885
STDMETHODIMP CpEpEngine::key_compromized(struct pEp_identity_s *ident)
vb@4
   886
{
vb@49
   887
    ::pEp_identity *_ident;
vb@4
   888
vb@49
   889
    assert(ident);
vb@4
   890
vb@49
   891
    try {
vb@49
   892
        _ident = new_identity(ident);
vb@49
   893
    }
vb@49
   894
    catch (bad_alloc&) {
vb@49
   895
        return E_OUTOFMEMORY;
vb@49
   896
    }
vb@49
   897
    catch (exception&) {
vb@49
   898
        return E_FAIL;
vb@49
   899
    }
vb@4
   900
vb@49
   901
    PEP_STATUS status = ::key_compromized(get_session(), _ident);
vb@49
   902
    free_identity(_ident);
vb@49
   903
vb@4
   904
    if (status == PEP_OUT_OF_MEMORY)
vb@4
   905
        return E_OUTOFMEMORY;
vb@4
   906
vb@4
   907
    if (status == PEP_KEY_NOT_FOUND)
vb@4
   908
        return FAIL(L"key not found");
vb@4
   909
vb@4
   910
    if (status != ::PEP_STATUS_OK)
vb@7
   911
        return FAIL(L"cannot revoke compromized key");
vb@4
   912
vb@4
   913
    return S_OK;
vb@4
   914
}
vb@4
   915
Edouard@55
   916
STDMETHODIMP CpEpEngine::key_reset_trust(struct pEp_identity_s *ident)
Edouard@53
   917
{
Edouard@53
   918
    ::pEp_identity *_ident;
Edouard@53
   919
Edouard@53
   920
    assert(ident);
Edouard@53
   921
Edouard@53
   922
    try {
Edouard@53
   923
        _ident = new_identity(ident);
Edouard@53
   924
    }
Edouard@53
   925
    catch (bad_alloc&) {
Edouard@53
   926
        return E_OUTOFMEMORY;
Edouard@53
   927
    }
Edouard@53
   928
    catch (exception&) {
Edouard@53
   929
        return E_FAIL;
Edouard@53
   930
    }
Edouard@53
   931
Edouard@55
   932
    PEP_STATUS status = ::key_reset_trust(get_session(), _ident);
Edouard@53
   933
    free_identity(_ident);
Edouard@53
   934
Edouard@53
   935
    if (status == PEP_OUT_OF_MEMORY)
Edouard@53
   936
        return E_OUTOFMEMORY;
Edouard@53
   937
Edouard@53
   938
    if (status == PEP_KEY_NOT_FOUND)
Edouard@53
   939
        return FAIL(L"key not found");
Edouard@53
   940
Edouard@53
   941
    if (status != ::PEP_STATUS_OK)
Edouard@53
   942
        return FAIL(L"cannot reset trust");
Edouard@53
   943
Edouard@53
   944
    return S_OK;
Edouard@53
   945
}
Edouard@53
   946
vb@28
   947
int CpEpEngine::examine_identity(pEp_identity *ident, void *management)
vb@28
   948
{
vb@28
   949
    assert(ident);
vb@28
   950
    assert(management);
vb@28
   951
    if (!(ident && management))
vb@28
   952
        return -1;
vb@28
   953
vb@28
   954
    CpEpEngine *me = (CpEpEngine *) management;
vb@28
   955
vb@28
   956
    if (me->identity_queue.load() == NULL)
vb@28
   957
        return 0;
vb@28
   958
vb@28
   959
    try {
vb@28
   960
        me->identity_queue.load()->push_back(ident);
vb@28
   961
    }
vb@28
   962
    catch (exception&) {
vb@28
   963
        return -1;
vb@28
   964
    }
vb@28
   965
vb@28
   966
    return 0;
vb@28
   967
}
vb@28
   968
vb@0
   969
::pEp_identity * CpEpEngine::retrieve_next_identity(void *management)
vb@0
   970
{
vb@0
   971
    assert(management);
vb@0
   972
    identity_queue_t *iq = (identity_queue_t *) management;
vb@0
   973
vb@0
   974
    do /* poll queue */ {
vb@0
   975
        if (iq->size())
vb@0
   976
            break;
vb@8
   977
        ::Sleep(100);
vb@0
   978
    } while (true);
vb@0
   979
vb@0
   980
    ::pEp_identity *_ident;
vb@0
   981
    pEp_identity_cpp& ident = iq->front();
vb@0
   982
vb@27
   983
    if (ident.address.size() == 0)
vb@0
   984
        return NULL;
vb@0
   985
vb@8
   986
    _ident = ident.to_pEp_identity();
vb@0
   987
    iq->pop_front();
vb@0
   988
vb@0
   989
    return _ident;
vb@0
   990
}
vb@0
   991
vb@74
   992
PEP_STATUS CpEpEngine::messageToSend(void * obj, const message *msg)
vb@74
   993
{
vb@75
   994
    assert(msg);
vb@75
   995
    if (msg == NULL)
vb@75
   996
        return PEP_ILLEGAL_VALUE;
vb@75
   997
vb@74
   998
    text_message _msg;
vb@82
   999
    memset(&_msg, 0, sizeof(text_message));
vb@82
  1000
vb@74
  1001
    text_message_from_C(&_msg, msg);
vb@74
  1002
    CpEpEngine *me = (CpEpEngine *) obj;
vb@75
  1003
    HRESULT r = me->Fire_MessageToSend(&_msg);
vb@75
  1004
    assert(r == S_OK);
vb@79
  1005
    clear_text_message(&_msg);
vb@75
  1006
    if (r == E_OUTOFMEMORY)
vb@75
  1007
        return PEP_OUT_OF_MEMORY;
vb@75
  1008
    if (r != S_OK)
vb@75
  1009
        return PEP_UNKNOWN_ERROR;
vb@75
  1010
vb@74
  1011
    return PEP_STATUS_OK;
vb@74
  1012
}
vb@74
  1013
vb@83
  1014
PEP_STATUS CpEpEngine::showHandshake(void * obj, const pEp_identity *self, const pEp_identity *partner)
vb@74
  1015
{
vb@75
  1016
    assert(self && partner);
vb@75
  1017
    if (!(self && partner))
vb@80
  1018
        return PEP_ILLEGAL_VALUE;
vb@80
  1019
vb@74
  1020
    pEp_identity_s _self;
vb@74
  1021
    copy_identity(&_self, self);
vb@74
  1022
    pEp_identity_s _partner;
vb@74
  1023
    copy_identity(&_partner, partner);
vb@74
  1024
    CpEpEngine *me = (CpEpEngine *) obj;
vb@80
  1025
    sync_handshake_result_s _result;
vb@80
  1026
    HRESULT r = me->Fire_ShowHandshake(&_self, &_partner, &_result);
vb@75
  1027
    assert(r == S_OK);
vb@78
  1028
    clear_identity_s(_self);
vb@78
  1029
    clear_identity_s(_partner);
vb@80
  1030
    if (r == E_OUTOFMEMORY)
vb@80
  1031
        return PEP_OUT_OF_MEMORY;
vb@75
  1032
    if (r != S_OK)
vb@80
  1033
        return PEP_UNKNOWN_ERROR;
vb@75
  1034
vb@83
  1035
    PEP_STATUS status = deliverHandshakeResult(me->get_session(), (sync_handshake_result) (int) _result);
vb@83
  1036
    return status;
vb@74
  1037
}
vb@74
  1038
vb@65
  1039
STDMETHODIMP CpEpEngine::blacklist_add(BSTR fpr)
vb@65
  1040
{
vb@65
  1041
    assert(fpr);
vb@65
  1042
vb@65
  1043
    string _fpr = utf8_string(fpr);
vb@65
  1044
    PEP_STATUS status = ::blacklist_add(get_session(), _fpr.c_str());
vb@65
  1045
    assert(status == PEP_STATUS_OK);
vb@65
  1046
    if (status != PEP_STATUS_OK)
vb@65
  1047
        return FAIL(L"blacklist_add failed in pEp engine");
vb@65
  1048
vb@65
  1049
    return S_OK;
vb@65
  1050
}
vb@65
  1051
vb@65
  1052
STDMETHODIMP CpEpEngine::blacklist_delete(BSTR fpr)
vb@65
  1053
{
vb@65
  1054
    assert(fpr);
vb@65
  1055
vb@65
  1056
    string _fpr = utf8_string(fpr);
vb@65
  1057
    PEP_STATUS status = ::blacklist_delete(get_session(), _fpr.c_str());
vb@65
  1058
    assert(status == PEP_STATUS_OK);
vb@65
  1059
    if (status != PEP_STATUS_OK)
vb@65
  1060
        return FAIL(L"blacklist_delete failed in pEp engine");
vb@65
  1061
vb@65
  1062
    return S_OK;
vb@65
  1063
}
vb@65
  1064
vb@65
  1065
STDMETHODIMP CpEpEngine::blacklist_is_listed(BSTR fpr, VARIANT_BOOL *listed)
vb@65
  1066
{
vb@65
  1067
    assert(fpr);
vb@65
  1068
    assert(listed);
vb@65
  1069
vb@65
  1070
    string _fpr = utf8_string(fpr);
vb@65
  1071
    bool result;
vb@65
  1072
    PEP_STATUS status = ::blacklist_is_listed(get_session(), _fpr.c_str(), &result);
vb@65
  1073
    assert(status == PEP_STATUS_OK);
vb@65
  1074
    if (status != PEP_STATUS_OK)
vb@65
  1075
        return FAIL(L"blacklist_is_listed failed in pEp engine");
vb@65
  1076
vb@65
  1077
    *listed = result ? VARIANT_TRUE : VARIANT_FALSE;
vb@65
  1078
    return S_OK;
vb@65
  1079
}
vb@65
  1080
vb@65
  1081
STDMETHODIMP CpEpEngine::blacklist_retrieve(SAFEARRAY **blacklist)
vb@65
  1082
{
vb@65
  1083
    assert(blacklist);
vb@65
  1084
vb@65
  1085
    ::stringlist_t *_blacklist = NULL;
vb@65
  1086
    PEP_STATUS status = ::blacklist_retrieve(get_session(), &_blacklist);
vb@65
  1087
    assert(status == PEP_STATUS_OK);
vb@65
  1088
    if (status != PEP_STATUS_OK)
vb@65
  1089
        return FAIL(L"blacklist_retrieve failed in pEp engine");
vb@65
  1090
    assert(_blacklist);
vb@65
  1091
vb@65
  1092
    *blacklist = string_array(_blacklist);
vb@65
  1093
    return S_OK;
vb@65
  1094
}
vb@65
  1095
vb@0
  1096
HRESULT CpEpEngine::error(_bstr_t msg)
vb@0
  1097
{
vb@0
  1098
    _bstr_t helpFile = L"";
vb@0
  1099
    _bstr_t source = L"pEp COM Adapter";
vb@0
  1100
vb@0
  1101
    ICreateErrorInfo *cei;
vb@0
  1102
    if (SUCCEEDED(CreateErrorInfo(&cei))) {
vb@0
  1103
        cei->SetDescription(msg);
vb@0
  1104
        cei->SetGUID(__uuidof(IpEpEngine));
vb@0
  1105
        cei->SetHelpContext(0);
vb@0
  1106
        cei->SetHelpFile(helpFile);
vb@0
  1107
        cei->SetSource(source);
vb@0
  1108
vb@0
  1109
        IErrorInfo *errinfo;
vb@0
  1110
        if (SUCCEEDED(cei->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &errinfo))) {
vb@0
  1111
            SetErrorInfo(0, errinfo);
vb@0
  1112
            errinfo->Release();
vb@0
  1113
        }
vb@0
  1114
        cei->Release();
vb@0
  1115
    }
vb@0
  1116
    return E_FAIL;
vb@0
  1117
}
vb@15
  1118
vb@37
  1119
STDMETHODIMP CpEpEngine::encrypt_message(text_message * src, text_message * dst, SAFEARRAY * extra)
vb@15
  1120
{
markus@150
  1121
	// this method is just a backwards compatibility wrapper
markus@150
  1122
	return encrypt_message_ex(src, dst, extra, pEp_enc_pieces);
markus@150
  1123
}
markus@150
  1124
markus@150
  1125
STDMETHODIMP CpEpEngine::encrypt_message_ex(text_message * src, text_message * dst, SAFEARRAY * extra, pEp_enc_format enc_format)
markus@150
  1126
{
vb@15
  1127
    assert(src);
vb@15
  1128
    assert(dst);
vb@15
  1129
vb@33
  1130
    ::message *_src = text_message_to_C(src);
vb@33
  1131
    ::message *msg_dst;
vb@33
  1132
    ::stringlist_t *_extra = new_stringlist(extra);
vb@16
  1133
markus@150
  1134
	// casting this value in a local variable allows for easier debugging.
markus@150
  1135
	PEP_enc_format engine_enc_format = (PEP_enc_format)enc_format;
markus@150
  1136
markus@150
  1137
    PEP_STATUS status = ::encrypt_message(get_session(), _src, _extra, &msg_dst, engine_enc_format);
vb@38
  1138
    ::free_stringlist(_extra);
vb@16
  1139
vb@46
  1140
    if (status == PEP_STATUS_OK)
vb@46
  1141
        text_message_from_C(dst, msg_dst);
vb@46
  1142
    else
vb@38
  1143
        text_message_from_C(dst, _src);
vb@38
  1144
vb@38
  1145
    ::free_message(msg_dst);
vb@38
  1146
    ::free_message(_src);
vb@16
  1147
vb@46
  1148
    if (status == PEP_OUT_OF_MEMORY)
vb@46
  1149
        return E_OUTOFMEMORY;
vb@46
  1150
vb@15
  1151
    return S_OK;
vb@15
  1152
}
vb@15
  1153
vb@37
  1154
STDMETHODIMP CpEpEngine::decrypt_message(text_message * src, text_message * dst, SAFEARRAY ** keylist, pEp_color *rating)
vb@15
  1155
{
vb@15
  1156
    assert(src);
vb@15
  1157
    assert(dst);
vb@18
  1158
    assert(keylist);
vb@19
  1159
    assert(rating);
vb@15
  1160
vb@40
  1161
    *keylist = NULL;
vb@41
  1162
    *rating = pEp_rating_undefined;
vb@40
  1163
vb@33
  1164
    ::message *_src = text_message_to_C(src);
vb@39
  1165
    ::message *msg_dst = NULL;
vb@18
  1166
    ::stringlist_t *_keylist;
vb@19
  1167
    ::PEP_color _rating;
vb@16
  1168
Edouard@105
  1169
    PEP_decrypt_flags_t flags = 0; 
Edouard@105
  1170
    PEP_STATUS status = ::decrypt_message(get_session(), _src, &msg_dst, &_keylist, &_rating, &flags);
Edouard@104
  1171
    // TODO : output decrypt flags.
vb@42
  1172
vb@42
  1173
    if (msg_dst)
vb@42
  1174
        text_message_from_C(dst, msg_dst);
vb@42
  1175
vb@39
  1176
    ::free_message(_src);
vb@42
  1177
    ::free_message(msg_dst);
vb@16
  1178
vb@19
  1179
    if (_keylist) {
vb@40
  1180
        *keylist = string_array(_keylist);
vb@33
  1181
        free_stringlist(_keylist);
vb@19
  1182
    }
vb@18
  1183
vb@19
  1184
    *rating = (pEp_color) _rating;
vb@18
  1185
vb@15
  1186
    return S_OK;
vb@15
  1187
}
vb@15
  1188
vb@33
  1189
STDMETHODIMP CpEpEngine::outgoing_message_color(text_message *msg, pEp_color * pVal)
vb@15
  1190
{
vb@15
  1191
    assert(msg);
vb@15
  1192
    assert(pVal);
vb@15
  1193
vb@33
  1194
    ::message *_msg = text_message_to_C(msg);
vb@19
  1195
vb@16
  1196
    PEP_color _color;
vb@33
  1197
    PEP_STATUS status = ::outgoing_message_color(get_session(), _msg, &_color);
vb@16
  1198
    if (status != PEP_STATUS_OK)
vb@19
  1199
        return FAIL(L"cannot get message color");
vb@16
  1200
vb@16
  1201
    *pVal = (pEp_color) _color;
vb@15
  1202
    return S_OK;
vb@15
  1203
}
vb@18
  1204
vb@18
  1205
STDMETHODIMP CpEpEngine::identity_color(struct pEp_identity_s *ident, pEp_color * pVal)
vb@18
  1206
{
vb@18
  1207
    ::pEp_identity *_ident;
vb@18
  1208
vb@18
  1209
    assert(ident);
vb@18
  1210
    assert(pVal);
vb@18
  1211
vb@18
  1212
    try {
vb@18
  1213
        _ident = new_identity(ident);
vb@18
  1214
    }
vb@22
  1215
    catch (bad_alloc&) {
vb@18
  1216
        return E_OUTOFMEMORY;
vb@18
  1217
    }
vb@22
  1218
    catch (exception&) {
vb@18
  1219
        return E_FAIL;
vb@18
  1220
    }
vb@18
  1221
vb@18
  1222
    PEP_color _color;
vb@18
  1223
    PEP_STATUS status = ::identity_color(get_session(), _ident, &_color);
vb@18
  1224
    free_identity(_ident);
vb@18
  1225
    if (status != PEP_STATUS_OK)
vb@19
  1226
        return FAIL(L"cannot get message color");
vb@18
  1227
vb@18
  1228
    *pVal = (pEp_color) _color;
vb@18
  1229
    return S_OK;
vb@18
  1230
}
vb@48
  1231
vb@50
  1232
STDMETHODIMP CpEpEngine::trust_personal_key(struct pEp_identity_s *ident, struct pEp_identity_s *result)
vb@48
  1233
{
vb@48
  1234
    ::pEp_identity *_ident;
vb@48
  1235
vb@48
  1236
    assert(ident);
vb@50
  1237
    assert(result);
vb@48
  1238
vb@48
  1239
    try {
vb@48
  1240
        _ident = new_identity(ident);
vb@48
  1241
    }
vb@48
  1242
    catch (bad_alloc&) {
vb@48
  1243
        return E_OUTOFMEMORY;
vb@48
  1244
    }
vb@48
  1245
    catch (exception&) {
vb@48
  1246
        return E_FAIL;
vb@48
  1247
    }
vb@48
  1248
vb@52
  1249
    if (verbose_mode) {
vb@52
  1250
        stringstream ss;
vb@52
  1251
        ss << "trust_personal_key called with ";
vb@52
  1252
        ss << utf8_string(ident->address);
vb@52
  1253
        ss << L": ";
vb@52
  1254
        ss << ident->comm_type;
vb@52
  1255
        verbose(ss.str());
vb@52
  1256
    }
vb@52
  1257
vb@48
  1258
    PEP_STATUS status = ::trust_personal_key(get_session(), _ident);
vb@52
  1259
vb@52
  1260
    if (verbose_mode) {
vb@52
  1261
        stringstream ss;
vb@52
  1262
        ss << "result ";
vb@52
  1263
        ss << status;
vb@52
  1264
        ss << " for ";
vb@52
  1265
        ss << _ident->address;
vb@52
  1266
        ss << L": ";
vb@52
  1267
        ss << _ident->comm_type;
vb@52
  1268
        verbose(ss.str());
vb@52
  1269
    }
vb@52
  1270
vb@50
  1271
    if (status == PEP_STATUS_OK)
vb@50
  1272
        copy_identity(result, _ident);
vb@50
  1273
vb@48
  1274
    free_identity(_ident);
vb@48
  1275
    if (status == PEP_OUT_OF_MEMORY)
vb@48
  1276
        return E_OUTOFMEMORY;
vb@48
  1277
    else if (status != PEP_STATUS_OK)
vb@48
  1278
        return FAIL(L"failure while executing trust_personal_key()");
vb@48
  1279
vb@48
  1280
    return S_OK;
vb@48
  1281
}
markus@84
  1282
markus@84
  1283
markus@84
  1284
// Event callbacks
markus@84
  1285
markus@84
  1286
STDMETHODIMP CpEpEngine::register_callbacks(IpEpEngineCallbacks* new_callbacks) 
markus@84
  1287
{
markus@84
  1288
	callbacks cbs = get_callbacks();
markus@84
  1289
	vector<IpEpEngineCallbacks*>& vec = cbs;
markus@84
  1290
markus@84
  1291
	vec.push_back(new_callbacks);
markus@84
  1292
	new_callbacks->AddRef();
markus@84
  1293
markus@84
  1294
	return S_OK;
markus@84
  1295
}
markus@84
  1296
markus@84
  1297
STDMETHODIMP CpEpEngine::unregister_callbacks(IpEpEngineCallbacks* obsolete_callbacks) 
markus@84
  1298
{
markus@84
  1299
	callbacks cbs = get_callbacks();
markus@84
  1300
	vector<IpEpEngineCallbacks*>& vec = cbs;
markus@84
  1301
markus@84
  1302
	auto position = std::find(vec.begin(), vec.end(), obsolete_callbacks);
markus@84
  1303
	if (position != vec.end()) {
markus@84
  1304
		vec.erase(position);
markus@84
  1305
		obsolete_callbacks->Release();
markus@84
  1306
		return S_OK;
markus@84
  1307
	}
markus@84
  1308
markus@84
  1309
	return S_FALSE;
markus@84
  1310
}
markus@84
  1311
markus@84
  1312
HRESULT CpEpEngine::Fire_MessageToSend(text_message * msg)
markus@84
  1313
{
markus@84
  1314
	callbacks cbs = get_callbacks();
markus@84
  1315
	vector<IpEpEngineCallbacks*>& vec = cbs;
markus@84
  1316
markus@84
  1317
	assert(msg);
markus@84
  1318
markus@84
  1319
	for (auto it = vec.begin(); it != vec.end(); ++it) 
markus@84
  1320
	{
markus@84
  1321
		auto res = (*it)->MessageToSend(msg);
markus@84
  1322
		if (res != S_OK)
markus@84
  1323
			return res;
markus@84
  1324
	}
markus@84
  1325
	return S_OK;
markus@84
  1326
}
markus@84
  1327
markus@84
  1328
HRESULT CpEpEngine::Fire_ShowHandshake(pEp_identity_s * self, pEp_identity_s * partner, sync_handshake_result_s * result)
markus@84
  1329
{
markus@84
  1330
	callbacks cbs = get_callbacks();
markus@84
  1331
	vector<IpEpEngineCallbacks*>& vec = cbs;
markus@84
  1332
markus@84
  1333
	assert(self);
markus@84
  1334
	assert(partner);
markus@84
  1335
	assert(result);
markus@84
  1336
markus@84
  1337
	for (auto it = vec.begin(); it != vec.end(); ++it)
markus@84
  1338
	{
markus@84
  1339
		auto res = (*it)->ShowHandshake(self, partner, result);
markus@84
  1340
		if (res != S_OK)
markus@84
  1341
			return res;
markus@84
  1342
	}
markus@84
  1343
	return S_OK;
markus@84
  1344
}