Browse Source

initial commit

COM-121
Volker Birk 7 years ago
commit
e77bd8725b
20 changed files with 1968 additions and 0 deletions
  1. +945
    -0
      CpEpEngine.cpp
  2. +197
    -0
      CpEpEngine.h
  3. +56
    -0
      ReadMe.txt
  4. +10
    -0
      _IpEpEngineEvents_CP.h
  5. +37
    -0
      dlldata.c
  6. +52
    -0
      locked_queue.hh
  7. +30
    -0
      pEpCOMServerAdapter.cpp
  8. +145
    -0
      pEpCOMServerAdapter.idl
  9. BIN
      pEpCOMServerAdapter.rc
  10. +172
    -0
      pEpCOMServerAdapter.vcxproj
  11. +145
    -0
      pEpComAdapter.idl
  12. +15
    -0
      pEpEngine.rgs
  13. BIN
      resource.h
  14. +5
    -0
      stdafx.cpp
  15. +41
    -0
      stdafx.h
  16. +11
    -0
      targetver.h
  17. +68
    -0
      utf8_helper.cpp
  18. +6
    -0
      utf8_helper.h
  19. +18
    -0
      xdlldata.c
  20. +15
    -0
      xdlldata.h

+ 945
- 0
CpEpEngine.cpp View File

@ -0,0 +1,945 @@
// CpEpEngine.cpp : Implementation of CpEpEngine
#include "stdafx.h"
#include "CpEpEngine.h"
// CpEpEngine
STDMETHODIMP CpEpEngine::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* const arr[] =
{
&IID_IpEpEngine
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
#define FAIL(msg) error(msg)
using namespace std;
static CComSafeArray<BSTR> string_array(const ::stringlist_t *stringlist)
{
CComSafeArray<BSTR> sa_string_list;
int n = 0;
for (const ::stringlist_t *k = stringlist; k != NULL; k = k->next) {
if (k->value) {
HRESULT _result = sa_string_list.Add(utf16_bstr(k->value).Detach(), false);
assert(_result == S_OK);
if (_result == E_OUTOFMEMORY)
throw std::bad_alloc();
++n;
}
}
return sa_string_list;
}
static ::stringlist_t * new_stringlist(const SAFEARRAY * safearray)
{
CComSafeArray<BSTR> sa(safearray);
int n_strings = 0;
::stringlist_t *_stringlist = ::new_stringlist((const char *) NULL);
assert(_stringlist);
if (_stringlist == NULL)
throw std::bad_alloc();
n_strings = sa.GetUpperBound() - sa.GetLowerBound() + 1;
::stringlist_t *k = _stringlist;
for (int i = 0, j = sa.GetLowerBound(); i<n_strings; ++i, ++j) {
k = ::stringlist_add(k, utf8_string(sa.GetAt(j)).c_str());
assert(k);
if (k == NULL) {
::free_stringlist(_stringlist);
throw std::bad_alloc();
}
}
return _stringlist;
}
static ::pEp_identity *new_identity(const pEp_identity_s * ident)
{
::pEp_identity *_ident;
string _address;
string _fpr;
string _user_id;
string _username;
if (ident->address)
_address = utf8_string(ident->address);
if (ident->fpr) {
_fpr = utf8_string(ident->fpr);
for (auto p = _fpr.begin(); p != _fpr.end(); ++p) {
if (*p >= 'A' && *p <= 'Z')
continue;
if (*p >= '0' && *p <= '9')
continue;
throw invalid_argument("invalid hex digits in fingerprint");
}
}
if (ident->user_id)
_user_id = utf8_string(ident->user_id);
if (ident->username)
_username = utf8_string(ident->username);
_ident = ::new_identity(_address.c_str(), _fpr.c_str(), _user_id.c_str(), _username.c_str());
assert(_ident);
if (_ident == NULL)
throw bad_alloc();
_ident->comm_type = (PEP_comm_type) ident->comm_type;
if (ident->lang) {
string _lang = utf8_string(ident->lang);
if (_lang.length() != 0) {
if (_lang.length() != 2) {
::free_identity(_ident);
throw invalid_argument("invalid language code");
}
if (_lang[0] < 'a' || _lang[0] > 'z') {
::free_identity(_ident);
throw invalid_argument("invalid language code");
}
if (_lang[1] < 'a' || _lang[1] > 'z') {
::free_identity(_ident);
throw invalid_argument("invalid language code");
}
_ident->lang[0] = _lang[0];
_ident->lang[1] = _lang[1];
}
}
return _ident;
}
static void copy_identity(pEp_identity_s * ident_s, const pEp_identity * ident)
{
::memset(ident_s, 0, sizeof(pEp_identity_s));
if (ident->address)
ident_s->address = utf16_bstr(ident->address).Detach();
if (ident->fpr)
ident_s->fpr = utf16_bstr(ident->fpr).Detach();
if (ident->user_id)
ident_s->user_id = utf16_bstr(ident->user_id).Detach();
if (ident->username)
ident_s->username = utf16_bstr(ident->username).Detach();
ident_s->comm_type = (pEp_comm_type) ident->comm_type;
if (ident->lang)
ident_s->lang = utf16_bstr(ident->lang).Detach();
}
// CpEpEngine
::pEp_identity *CpEpEngine::new_identity(const CpEpEngine::pEp_identity_cpp& ident)
{
::pEp_identity *_ident = ::new_identity(ident.address.c_str(), ident.fpr.c_str(), ident.user_id.c_str(), ident.username.c_str());
assert(_ident);
if (_ident == NULL)
throw bad_alloc();
_ident->comm_type = (::PEP_comm_type) ident.comm_type;
_ident->me = ident.me;
assert(ident.lang.size() == 0 || ident.lang.size() == 2);
if (ident.lang.size()) {
_ident->lang[0] = ident.lang[0];
_ident->lang[1] = ident.lang[1];
}
return _ident;
}
STDMETHODIMP CpEpEngine::log(BSTR title, BSTR entity, BSTR description, BSTR comment)
{
string _title;
string _entity;
string _description;
string _comment;
HRESULT result = S_OK;
assert(title);
if (title)
_title = utf8_string(title);
else
result = E_INVALIDARG;
assert(entity);
if (entity)
_entity = utf8_string(entity);
else
result = E_INVALIDARG;
if (description)
_description = utf8_string(description);
if (comment)
_comment = utf8_string(comment);
if (result != S_OK)
return result;
PEP_STATUS _status = ::log_event(get_session(), _title.c_str(), _entity.c_str(), _description.c_str(), _comment.c_str());
assert(_status == PEP_STATUS_OK);
if (_status != PEP_STATUS_OK)
return FAIL(L"log_event");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::decrypt(BSTR ctext, BSTR * ptext, LPSAFEARRAY * key_list, pEp_STATUS * status)
{
assert(ctext);
assert(ptext);
assert(key_list);
assert(status);
if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
if (ptext)
*ptext = NULL;
if (key_list)
*key_list = NULL;
if (status)
*status = pEp_UNENCRYPTED;
return E_INVALIDARG;
}
string _ctext = utf8_string(ctext);
char *_ptext = NULL;
size_t _psize = 0;
::stringlist_t *_keylist = NULL;
PEP_STATUS _status;
_status = ::decrypt_and_verify(get_session(), _ctext.c_str(), _ctext.size(), &_ptext, &_psize, &_keylist);
assert(_status != PEP_OUT_OF_MEMORY);
if (_status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
*status = (pEp_STATUS) _status;
if (_ptext == NULL) {
if (_keylist) {
string msg;
if (_keylist->value[0] != 0) {
msg = _keylist->value;
}
else {
for (::stringlist_t *s = _keylist->next; s != NULL; s = s->next) {
if (s->value) {
msg += s->value;
msg += ";";
}
}
}
::free_stringlist(_keylist);
return FAIL(utf16_bstr(msg));
}
else
return FAIL(L"cannot decrypt");
}
*ptext = utf16_bstr(_ptext).Detach();
pEp_free(_ptext);
if (_keylist && _keylist->value)
*key_list = string_array(_keylist).Detach();
else
*key_list = NULL;
::free_stringlist(_keylist);
return S_OK;
}
STDMETHODIMP CpEpEngine::decrypt_b(BSTR ctext, LPSAFEARRAY * ptext, LPSAFEARRAY * key_list, pEp_STATUS * status)
{
assert(ctext);
assert(ptext);
assert(key_list);
assert(status);
if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
if (ptext)
*ptext = NULL;
if (key_list)
*key_list = NULL;
if (status)
*status = pEp_UNENCRYPTED;
return E_INVALIDARG;
}
// Welcome to Windoze string hell!
char *_ctext = NULL;
_bstr_t bstr_ctext(ctext, true);
int w_csize = bstr_ctext.length() + 1;
int _csize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, (wchar_t *) bstr_ctext, w_csize, NULL, 0, NULL, NULL);
if (_csize) {
_ctext = new char[_csize];
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, (wchar_t *) bstr_ctext, w_csize, _ctext, _csize, NULL, NULL);
}
char *_ptext = NULL;
size_t _psize = 0;
::stringlist_t *_keylist = NULL;
PEP_STATUS _status;
_status = ::decrypt_and_verify(get_session(), _ctext, _csize, &_ptext, &_psize, &_keylist);
assert(_status != PEP_OUT_OF_MEMORY);
delete[] _ctext;
if (_status == PEP_OUT_OF_MEMORY) {
::free_stringlist(_keylist);
return E_OUTOFMEMORY;
}
*status = (pEp_STATUS) _status;
if (_ptext == NULL) {
::free_stringlist(_keylist);
return FAIL(L"decrypt_and_verify");
}
CComSafeArray<BYTE> sa_ptext;
HRESULT _result = sa_ptext.Create(_psize, 0);
assert(_result == S_OK);
if (_result == E_OUTOFMEMORY) {
pEp_free(_ptext);
::free_stringlist(_keylist);
return E_OUTOFMEMORY;
}
else if (_result != S_OK) {
pEp_free(_ptext);
::free_stringlist(_keylist);
return FAIL(L"CComSafeArray<BYTE>::Create");
}
memcpy(sa_ptext.m_psa->pvData, _ptext, _psize);
*ptext = sa_ptext.Detach();
::pEp_free(_ptext);
if (_keylist && _keylist->value)
*key_list = string_array(_keylist).Detach();
else
*key_list = NULL;
::free_stringlist(_keylist);
return S_OK;
}
STDMETHODIMP CpEpEngine::verify(BSTR text, BSTR signature, LPSAFEARRAY * key_list, pEp_STATUS * verify_status)
{
assert(text);
assert(signature);
assert(key_list);
if (text == NULL || signature == NULL || key_list == NULL)
return E_INVALIDARG;
string _text = utf8_string(text);
string _signature = utf8_string(signature);
::stringlist_t *_keylist = NULL;
PEP_STATUS _status;
_status = ::verify_text(get_session(), _text.c_str(), _text.size(), _signature.c_str(), _signature.size(), &_keylist);
assert(_status != PEP_OUT_OF_MEMORY);
if (_status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (_status == PEP_DECRYPT_WRONG_FORMAT || _status == PEP_UNKNOWN_ERROR)
return FAIL(L"verify_text");
*verify_status = (pEp_STATUS) _status;
if (_keylist && _keylist->value)
*key_list = string_array(_keylist).Detach();
else
*key_list = NULL;
::free_stringlist(_keylist);
return S_OK;
}
STDMETHODIMP CpEpEngine::encrypt(SAFEARRAY * key_list, BSTR ptext, BSTR * ctext, pEp_STATUS * status)
{
assert(key_list);
assert(ptext);
assert(ctext);
assert(status);
if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
if (ctext)
*ctext = NULL;
if (status)
*status = pEp_UNKNOWN_ERROR;
return E_INVALIDARG;
}
HRESULT result = S_OK;
::stringlist_t *_keylist = new_stringlist(key_list);
string _ptext = utf8_string(ptext);
char *_ctext = NULL;
size_t _csize = 0;
PEP_STATUS _status;
_status = ::encrypt_and_sign(get_session(), _keylist, _ptext.c_str(), _ptext.size(), &_ctext, &_csize);
assert(_status != PEP_OUT_OF_MEMORY);
::free_stringlist(_keylist);
if (_status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
*status = (pEp_STATUS) _status;
if (_ctext == NULL)
return FAIL(L"encrypt_and_sign");
*ctext = utf16_bstr(_ctext).Detach();
pEp_free(_ctext);
return S_OK;
}
STDMETHODIMP CpEpEngine::encrypt_b(SAFEARRAY * key_list, SAFEARRAY * ptext, BSTR * ctext, pEp_STATUS * status)
{
assert(key_list);
assert(ptext);
assert(ctext);
assert(status);
if (ctext == NULL || ptext == NULL || key_list == NULL || status == NULL) {
if (ctext)
*ctext = NULL;
if (status)
*status = pEp_UNKNOWN_ERROR;
return E_INVALIDARG;
}
HRESULT result = S_OK;
::stringlist_t *_keylist = new_stringlist(key_list);
char *_ctext = NULL;
size_t _csize = 0;
::PEP_STATUS _status;
_status = ::encrypt_and_sign(get_session(), _keylist, (const char *) ptext->pvData, ptext->rgsabound[0].cElements, &_ctext, &_csize);
assert(_status != PEP_OUT_OF_MEMORY);
::free_stringlist(_keylist);
if (_status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
*status = (pEp_STATUS) _status;
if (_ctext == NULL)
return FAIL(L"encrypt_and_sign");
*status = (pEp_STATUS) _status;
wchar_t *w_ctext = NULL;
int w_csize = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _ctext, _csize, NULL, 0);
if (w_csize) {
w_ctext = new wchar_t[w_csize + 1];
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _ctext, _csize, w_ctext, w_csize);
w_ctext[w_csize] = 0; // this is for debugging; Visual Studio will crash without that if you're unlucky
}
*ctext = ::SysAllocStringLen(w_ctext, w_csize);
assert(ctext);
delete[] w_ctext;
pEp_free(_ctext);
if (ctext == NULL)
return E_OUTOFMEMORY;
return S_OK;
}
STDMETHODIMP CpEpEngine::safeword(LONG value, BSTR lang, BSTR * word)
{
assert(value >= 0 && value <= 65535);
assert(word);
HRESULT result = S_OK;
uint16_t _value = 0;
if (value < 0 || value > 65535)
result = E_INVALIDARG;
else
_value = (uint16_t) value;
string _lang = "en";
if (lang) {
_lang = utf8_string(lang);
if (_lang.length() != 2)
result = E_INVALIDARG;
}
if (word == NULL)
result = E_INVALIDARG;
if (result != S_OK)
return result;
char *_word = NULL;
size_t _wsize = 0;
PEP_STATUS status = ::safeword(get_session(), _value, _lang.c_str(), &_word, &_wsize);
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (_word == NULL) {
*word = NULL;
return FAIL(L"safeword");
}
else {
*word = utf16_bstr(_word).Detach();
pEp_free(_word);
return S_OK;
}
}
STDMETHODIMP CpEpEngine::safewords(BSTR fpr, BSTR lang, LONG max_words, BSTR * words)
{
assert(fpr);
assert(max_words >= 0);
assert(words);
HRESULT result = S_OK;
string _fpr;
if (fpr)
_fpr = utf8_string(fpr);
else
result = E_INVALIDARG;
string _lang;
if (lang) {
_lang = utf8_string(lang);
if (_lang.length()) {
if (_lang.length() != 2)
result = E_INVALIDARG;
}
else
_lang = "en";
}
else
_lang = "en";
if (max_words < 0)
result = E_INVALIDARG;
if (words == NULL)
result = E_INVALIDARG;
if (result != S_OK)
return result;
char *_words = NULL;
size_t _wsize = 0;
PEP_STATUS status = ::safewords(get_session(), _fpr.c_str(), _lang.c_str(), &_words, &_wsize, max_words);
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (_words == NULL) {
*words = NULL;
return FAIL(L"safewords");
}
else {
*words = utf16_bstr(_words).Detach();
pEp_free(_words);
return S_OK;
}
}
STDMETHODIMP CpEpEngine::get_identity(BSTR address, pEp_identity_s * ident)
{
assert(address);
assert(ident);
if (address == NULL)
return E_INVALIDARG;
if (ident == NULL)
return E_INVALIDARG;
string _address = utf8_string(address);
::pEp_identity *_ident = NULL;
PEP_STATUS status = ::get_identity(get_session(), _address.c_str(), &_ident);
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (_ident == NULL) {
return FAIL(L"get_identity");
}
copy_identity(ident, _ident);
::free_identity(_ident);
return S_OK;
}
STDMETHODIMP CpEpEngine::set_identity(pEp_identity_s * ident)
{
assert(ident);
assert(ident->address);
assert(ident->fpr);
assert(ident->username);
assert(ident->user_id);
if (ident == NULL || ident->address == NULL || ident->fpr == NULL
|| ident->username == NULL || ident->user_id == NULL)
return E_INVALIDARG;
::pEp_identity *_ident = new_identity(ident);
::PEP_STATUS status = ::set_identity(get_session(), _ident);
::free_identity(_ident);
if (status != ::PEP_STATUS_OK)
return FAIL(L"set_identity");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::generate_keypair(pEp_identity_s * ident, BSTR * fpr)
{
assert(ident);
assert(ident->address);
assert(ident->username);
assert(fpr);
if (ident == NULL || ident->address == NULL || ident->username == NULL || fpr == NULL)
return E_INVALIDARG;
::pEp_identity *_ident = new_identity(ident);
::pEp_free(_ident->fpr);
_ident->fpr = NULL;
::PEP_STATUS status = ::generate_keypair(get_session(), _ident);
assert(status != ::PEP_OUT_OF_MEMORY);
if (status == ::PEP_OUT_OF_MEMORY) {
::free_identity(_ident);
return E_OUTOFMEMORY;
}
if (_ident->fpr)
*fpr = utf16_bstr(_ident->fpr).Detach();
::free_identity(_ident);
if (status != ::PEP_STATUS_OK)
return FAIL(L"generate_keypair");
return S_OK;
}
STDMETHODIMP CpEpEngine::delete_keypair(BSTR fpr)
{
assert(fpr);
if (fpr == NULL)
return E_INVALIDARG;
string _fpr = utf8_string(fpr);
::PEP_STATUS status = ::delete_keypair(get_session(), _fpr.c_str());
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != ::PEP_STATUS_OK)
return FAIL(L"delete_keypair");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::import_key(BSTR key_data)
{
assert(key_data);
if (key_data == NULL)
return E_INVALIDARG;
string _key_data = utf8_string(key_data);
PEP_STATUS status = ::import_key(get_session(), _key_data.c_str(), _key_data.length());
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != pEp_STATUS_OK)
return FAIL(L"import_key");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::import_key_b(SAFEARRAY * key_data)
{
assert(key_data);
if (key_data == NULL)
return E_INVALIDARG;
::PEP_STATUS status = ::import_key(get_session(), (const char *) key_data->pvData, key_data->rgsabound[0].cElements);
assert(status != ::PEP_OUT_OF_MEMORY);
if (status == ::PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != ::PEP_STATUS_OK)
return FAIL(L"import_key");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::export_key(BSTR fpr, BSTR * key_data)
{
assert(fpr);
assert(key_data);
if (fpr == NULL || key_data == NULL)
return E_INVALIDARG;
string _fpr = utf8_string(fpr);
char *_key_data = NULL;
size_t _size = 0;
::PEP_STATUS status = ::export_key(get_session(), _fpr.c_str(), &_key_data, &_size);
assert(status != ::PEP_OUT_OF_MEMORY);
if (status == ::PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != ::PEP_STATUS_OK)
return FAIL(L"export_key");
_bstr_t b_key_data(utf16_string(_key_data).c_str());
pEp_free(_key_data);
*key_data = b_key_data.Detach();
return S_OK;
}
STDMETHODIMP CpEpEngine::recv_key(BSTR pattern)
{
assert(pattern);
if (pattern == NULL)
return E_INVALIDARG;
string _pattern = utf8_string(pattern);
PEP_STATUS status = ::recv_key(get_session(), _pattern.c_str());
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != ::PEP_STATUS_OK)
return FAIL(L"recv_key");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::find_keys(BSTR pattern, LPSAFEARRAY * key_list)
{
assert(pattern);
assert(key_list);
if (pattern == NULL || key_list == NULL)
return E_INVALIDARG;
string _pattern = utf8_string(pattern);
::stringlist_t *_keylist = NULL;
PEP_STATUS status = ::find_keys(get_session(), _pattern.c_str(), &_keylist);
assert(status != PEP_OUT_OF_MEMORY);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
if (status != ::PEP_STATUS_OK)
return FAIL(L"find_keys");
if (_keylist && _keylist->value) {
*key_list = string_array(_keylist).Detach();
}
else {
::free_stringlist(_keylist);
return FAIL(L"find_keys: no keys found");
}
::free_stringlist(_keylist);
return S_OK;
}
STDMETHODIMP CpEpEngine::send_key(BSTR pattern)
{
assert(pattern);
if (pattern == NULL)
return E_INVALIDARG;
string _pattern = utf8_string(pattern);
::PEP_STATUS status = ::send_key(get_session(), _pattern.c_str());
if (status != ::PEP_STATUS_OK)
return FAIL(L"send_key");
else
return S_OK;
}
STDMETHODIMP CpEpEngine::examine_identity(pEp_identity_s * ident)
{
assert(ident);
if (ident == NULL)
return E_INVALIDARG;
try {
identity_queue->push_back(ident);
}
catch (bad_alloc) {
return E_OUTOFMEMORY;
}
return S_OK;
}
STDMETHODIMP CpEpEngine::examine_myself(pEp_identity_s * myself)
{
assert(myself);
if (myself == NULL)
return E_INVALIDARG;
pEp_identity_cpp _ident(myself);
_ident.me = true;
::log_event(get_session(), "examine_myself", "debug", _ident.address.c_str(), NULL);
try {
identity_queue->push_front(_ident);
}
catch (bad_alloc) {
return E_OUTOFMEMORY;
}
return S_OK;
}
STDMETHODIMP CpEpEngine::myself(struct pEp_identity_s *ident, struct pEp_identity_s *result)
{
assert(ident);
assert(result);
if (ident == NULL || result == NULL)
return E_INVALIDARG;
::pEp_identity *_ident = new_identity(ident);
assert(_ident);
if (_ident == NULL)
return E_OUTOFMEMORY;
PEP_STATUS status = ::myself(get_session(), _ident);
if (status == PEP_STATUS_OK) {
assert(_ident->fpr);
copy_identity(result, _ident);
::free_identity(_ident);
return S_OK;
}
else {
::free_identity(_ident);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
else
return FAIL(L"myself");
}
}
STDMETHODIMP CpEpEngine::update_identity(struct pEp_identity_s *ident, struct pEp_identity_s *result)
{
assert(ident);
assert(result);
if (ident == NULL || result == NULL)
return E_INVALIDARG;
::pEp_identity *_ident = new_identity(ident);
assert(_ident);
if (_ident == NULL)
return E_OUTOFMEMORY;
PEP_STATUS status = ::update_identity(get_session(), _ident);
if (status == PEP_STATUS_OK) {
assert(_ident->fpr);
copy_identity(result, _ident);
if (_ident->comm_type == PEP_ct_unknown || _ident->comm_type == PEP_ct_key_expired) {
pEp_identity_cpp _ident_cpp(_ident);
identity_queue->push_back(_ident_cpp);
}
::free_identity(_ident);
return S_OK;
}
else {
::free_identity(_ident);
if (status == PEP_OUT_OF_MEMORY)
return E_OUTOFMEMORY;
else
return FAIL(L"update_identity");
}
}
::pEp_identity * CpEpEngine::retrieve_next_identity(void *management)
{
assert(management);
identity_queue_t *iq = (identity_queue_t *) management;
do /* poll queue */ {
if (iq->size())
break;
::Sleep(100);
} while (true);
::pEp_identity *_ident;
pEp_identity_cpp& ident = iq->front();
if (ident.address.size() == 0) {
delete iq;
return NULL;
}
_ident = new_identity(ident);
iq->pop_front();
return _ident;
}
HRESULT CpEpEngine::error(_bstr_t msg)
{
_bstr_t helpFile = L"";
_bstr_t source = L"pEp COM Adapter";
ICreateErrorInfo *cei;
if (SUCCEEDED(CreateErrorInfo(&cei))) {
cei->SetDescription(msg);
cei->SetGUID(__uuidof(IpEpEngine));
cei->SetHelpContext(0);
cei->SetHelpFile(helpFile);
cei->SetSource(source);
IErrorInfo *errinfo;
if (SUCCEEDED(cei->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &errinfo))) {
SetErrorInfo(0, errinfo);
errinfo->Release();
}
cei->Release();
}
return E_FAIL;
}

+ 197
- 0
CpEpEngine.h View File

@ -0,0 +1,197 @@
// CpEpEngine.h : Declaration of the CpEpEngine
#pragma once
#include "resource.h" // main symbols
#include "pEpComServerAdapter_i.h"
#include "_IpEpEngineEvents_CP.h"
#include "locked_queue.hh"
#include "utf8_helper.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#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."
#endif
using namespace ATL;
using namespace utility;
// CpEpEngine
class ATL_NO_VTABLE CpEpEngine :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CpEpEngine, &CLSID_pEpEngine>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CpEpEngine>,
public CProxy_IpEpEngineEvents<CpEpEngine>,
public IpEpEngine
{
public:
CpEpEngine()
{
PEP_STATUS status = ::init(&m_session);
assert(status == PEP_STATUS_OK);
::log_event(m_session, "Startup", "pEp COM Adapter", NULL, NULL);
identity_queue = new identity_queue_t();
keymanagement_thread = new thread(::do_keymanagement, retrieve_next_identity, (void *) identity_queue);
keymanagement_thread->detach();
}
~CpEpEngine()
{
pEp_identity_cpp shutdown;
identity_queue->push_front(shutdown);
::log_event(m_session, "Shutdown", "pEp COM Adapter", NULL, NULL);
::release(m_session);
}
DECLARE_REGISTRY_RESOURCEID(IDR_PEPENGINE)
DECLARE_NOT_AGGREGATABLE(CpEpEngine)
BEGIN_COM_MAP(CpEpEngine)
COM_INTERFACE_ENTRY(IpEpEngine)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CpEpEngine)
CONNECTION_POINT_ENTRY(__uuidof(_IpEpEngineEvents))
END_CONNECTION_POINT_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
protected:
struct pEp_identity_cpp {
std::string address;
std::string fpr;
std::string user_id;
std::string username;
pEp_comm_type comm_type;
std::string lang;
bool me;
pEp_identity_cpp(
std::string _address = std::string(),
std::string _fpr = std::string(),
std::string _user_id = std::string(),
std::string _username = std::string(),
pEp_comm_type _comm_type = pEp_ct_unknown,
std::string _lang = std::string()
) : address(_address), fpr(_fpr), user_id(_user_id), username(_username), comm_type(_comm_type), lang(_lang), me(false)
{ }
pEp_identity_cpp(const ::pEp_identity *_ident)
: me(false)
{
if (_ident->address)
address = _ident->address;
if (_ident->fpr)
fpr = _ident->fpr;
if (_ident->user_id)
user_id = _ident->user_id;
if (_ident->username)
username = _ident->username;
comm_type = (pEp_comm_type) _ident->comm_type;
lang = _ident->lang;
}
pEp_identity_cpp(const pEp_identity_s *_ident)
: me(false)
{
if (_ident->address)
address = utf8_string(_ident->address);
if (_ident->fpr)
fpr = utf8_string(_ident->fpr);
if (_ident->user_id)
user_id = utf8_string(_ident->user_id);
if (_ident->username)
username = utf8_string(_ident->username);
comm_type = _ident->comm_type;
if (_ident->lang)
lang = utf8_string(_ident->lang);
}
};
class session
{
private:
CpEpEngine *me;
public:
session(CpEpEngine *myself)
{
me = myself;
me->session_mutex.lock();
}
~session()
{
me->session_mutex.unlock();
}
operator PEP_SESSION const ()
{
return me->m_session;
}
};
session get_session()
{
return session(this);
}
static ::pEp_identity *new_identity(const pEp_identity_cpp&);
typedef locked_queue<pEp_identity_cpp> identity_queue_t;
static ::pEp_identity * retrieve_next_identity(void *management);
HRESULT error(_bstr_t msg);
private:
PEP_SESSION m_session;
mutex session_mutex;
identity_queue_t *identity_queue;
thread *keymanagement_thread;
public:
STDMETHOD(log)(BSTR title, BSTR entity, BSTR description, BSTR comment);
STDMETHOD(decrypt)(BSTR ctext, BSTR * ptext, LPSAFEARRAY * key_list, pEp_STATUS * decrypt_status);
STDMETHOD(decrypt_b)(BSTR ctext, LPSAFEARRAY * ptext, LPSAFEARRAY * key_list, pEp_STATUS * decrypt_status);
STDMETHOD(encrypt)(SAFEARRAY * key_list, BSTR ptext, BSTR * ctext, pEp_STATUS * status);
STDMETHOD(encrypt_b)(SAFEARRAY * key_list, SAFEARRAY * ptext, BSTR * ctext, pEp_STATUS * status);
STDMETHOD(safeword)(LONG value, BSTR lang, BSTR * word);
STDMETHOD(safewords)(BSTR fpr, BSTR lang, LONG max_words, BSTR * words);
STDMETHOD(get_identity)(BSTR address, pEp_identity_s * ident);
STDMETHOD(set_identity)(pEp_identity_s * ident);
STDMETHOD(generate_keypair)(pEp_identity_s * ident, BSTR * fpr);
STDMETHOD(delete_keypair)(BSTR fpr);
STDMETHOD(import_key)(BSTR key_data);
STDMETHOD(import_key_b)(SAFEARRAY * key_data);
STDMETHOD(export_key)(BSTR fpr, BSTR * key_data);
STDMETHOD(recv_key)(BSTR pattern);
STDMETHOD(find_keys)(BSTR pattern, LPSAFEARRAY * key_list);
STDMETHOD(send_key)(BSTR pattern);
STDMETHOD(examine_identity)(pEp_identity_s * ident);
STDMETHOD(examine_myself)(pEp_identity_s * myself);
STDMETHOD(verify)(BSTR text, BSTR signature, LPSAFEARRAY * key_list, pEp_STATUS * verify_status);
STDMETHOD(myself)(struct pEp_identity_s *ident, struct pEp_identity_s *result);
STDMETHOD(update_identity)(struct pEp_identity_s *ident, struct pEp_identity_s *result);
};
OBJECT_ENTRY_AUTO(__uuidof(pEpEngine), CpEpEngine)

+ 56
- 0
ReadMe.txt View File

@ -0,0 +1,56 @@
========================================================================
ACTIVE TEMPLATE LIBRARY : pEpCOMServerAdapter Project Overview
========================================================================
AppWizard has created this pEpCOMServerAdapter project for you to use as the starting point for
writing your Executable (EXE).
This file contains a summary of what you will find in each of the files that
make up your project.
pEpCOMServerAdapter.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
pEpCOMServerAdapter.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
pEpCOMServerAdapter.idl
This file contains the IDL definitions of the type library, the interfaces
and co-classes defined in your project.
This file will be processed by the MIDL compiler to generate:
C++ interface definitions and GUID declarations (pEpCOMServerAdapter.h)
GUID definitions (pEpCOMServerAdapter_i.c)
A type library (pEpCOMServerAdapter.tlb)
Marshaling code (pEpCOMServerAdapter_p.c and dlldata.c)
pEpCOMServerAdapter.h
This file contains the C++ interface definitions and GUID declarations of the
items defined in pEpCOMServerAdapter.idl. It will be regenerated by MIDL during compilation.
pEpCOMServerAdapter.cpp
This file contains the object map and the implementation of WinMain.
pEpCOMServerAdapter.rc
This is a listing of all of the Microsoft Windows resources that the
program uses.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named pEpCOMServerAdapter.pch and a precompiled types file named StdAfx.obj.
Resource.h
This is the standard header file that defines resource IDs.
/////////////////////////////////////////////////////////////////////////////

+ 10
- 0
_IpEpEngineEvents_CP.h View File

@ -0,0 +1,10 @@
#pragma once
using namespace ATL;
template <class T>
class CProxy_IpEpEngineEvents : public IConnectionPointImpl<T, &__uuidof( _IpEpEngineEvents ), CComDynamicUnkArray>
{
// WARNING: This class may be regenerated by the wizard
public:
};

+ 37
- 0
dlldata.c View File

@ -0,0 +1,37 @@
/*********************************************************
DllData file -- generated by MIDL compiler
DO NOT ALTER THIS FILE
This file is regenerated by MIDL on every IDL file compile.
To completely reconstruct this file, delete it and rerun MIDL
on all the IDL files in this DLL, specifying this file for the
/dlldata command line option
*********************************************************/
#include <rpcproxy.h>
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_PROXY_FILE( pEpCOMServerAdapter )
PROXYFILE_LIST_START
/* Start of list */
REFERENCE_PROXY_FILE( pEpCOMServerAdapter ),
/* End of list */
PROXYFILE_LIST_END
DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )
#ifdef __cplusplus
} /*extern "C" */
#endif
/* end of generated dlldata file */

+ 52
- 0
locked_queue.hh View File

@ -0,0 +1,52 @@
#pragma once
#include <list>
#include <mutex>
namespace utility
{
using namespace std;
template<class T> class locked_queue
{
mutex _mtx;
list<T> _q;
public:
T& back()
{
lock_guard<mutex> lg(_mtx);
return _q.back();
}
T& front()
{
lock_guard<mutex> lg(_mtx);
return _q.front();
}
void pop_back()
{
lock_guard<mutex> lg(_mtx);
_q.pop_back();
}
void pop_front()
{
lock_guard<mutex> lg(_mtx);
_q.pop_front();
}
void push_back(const T& data)
{
lock_guard<mutex> lg(_mtx);
_q.push_back(data);
}
void push_front(const T& data)
{
lock_guard<mutex> lg(_mtx);
_q.push_front(data);
}
size_t size()
{
lock_guard<mutex> lg(_mtx);
return _q.size();
}
};
};

+ 30
- 0
pEpCOMServerAdapter.cpp View File

@ -0,0 +1,30 @@
// pEpCOMServerAdapter.cpp : Implementation of WinMain
#include "stdafx.h"
#include "resource.h"
#include "pEpCOMServerAdapter_i.h"
#include "xdlldata.h"
using namespace ATL;
class CpEpCOMServerAdapterModule : public ATL::CAtlExeModuleT< CpEpCOMServerAdapterModule >
{
public :
DECLARE_LIBID(LIBID_pEpCOMServerAdapterLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PEPCOMSERVERADAPTER, "{B3480081-82C0-4EE4-9AA1-3F513C9D78DD}")
};
CpEpCOMServerAdapterModule _AtlModule;
//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
return _AtlModule.WinMain(nShowCmd);
}

+ 145
- 0
pEpCOMServerAdapter.idl View File

@ -0,0 +1,145 @@
// pEpCOMServerAdapter.idl : IDL source for pEpCOMServerAdapter
//
// This file will be processed by the MIDL tool to
// produce the type library (pEpCOMServerAdapter.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540),
oleautomation,
nonextensible,
pointer_default(unique)
]
interface IpEpEngine : IUnknown {
typedef enum _pEp_STATUS {
pEp_STATUS_OK = 0,
pEp_KEY_NOT_FOUND = 0x0201,
pEp_KEY_HAS_AMBIG_NAME = 0x0202,
pEp_GET_KEY_FAILED = 0x0203,
pEp_UNENCRYPTED = 0x0400,
pEp_VERIFIED = 0x0401,
pEp_DECRYPTED = 0x0402,
pEp_DECRYPTED_AND_VERIFIED = 0x0403,
pEp_DECRYPT_WRONG_FORMAT = 0x0404,
pEp_DECRYPT_NO_KEY = 0x0405,
pEp_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406,
pEp_VERIFY_NO_KEY = 0x0407,
pEp_VERIFIED_AND_TRUSTED = 0x0408,
pEp_ILLEGAL_VALUE = -4,
pEp_BUFFER_TOO_SMALL = -3,
pEp_OUT_OF_MEMORY = -2,
pEp_UNKNOWN_ERROR = -1
} pEp_STATUS;
[id(1)] HRESULT log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment);
[id(2)] HRESULT decrypt([in] BSTR ctext, [out] BSTR * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
[id(3)] HRESULT decrypt_b([in] BSTR ctext, [out] SAFEARRAY(BYTE) * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
[id(4)] HRESULT encrypt([in] SAFEARRAY(BSTR) key_list, [in] BSTR ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
[id(5)] HRESULT encrypt_b([in] SAFEARRAY(BSTR) key_list, [in] SAFEARRAY(BYTE) ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
[id(21)] HRESULT verify([in] BSTR text, [in] BSTR signature, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * verify_status);
[id(6)] HRESULT safeword([in] LONG value, [in, defaultvalue("en")] BSTR lang, [out, retval] BSTR * word);
[id(7)] HRESULT safewords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG max_words, [out, retval] BSTR * words);
typedef enum _pEp_comm_type {
pEp_ct_unknown = 0,
// range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable
pEp_ct_no_encryption = 0x01, // generic
pEp_ct_no_encrypted_channel = 0x02,
pEp_ct_key_not_found = 0x03,
pEp_ct_key_expired = 0x04,
pEp_ct_key_revoked = 0x05,
pEp_ct_key_b0rken = 0x06,
pEp_ct_my_key_not_included = 0x09,
pEp_ct_security_by_obscurity = 0x0a,
pEp_ct_b0rken_crypto = 0x0b,
pEp_ct_key_too_short = 0x0e,
pEp_ct_compromized = 0x0f, // known compromized connection
// range 0x10 to 0x3f: unconfirmed encryption
pEp_ct_unconfirmed_encryption = 0x10, // generic
pEp_ct_OpenPGP_1024_RSA_unconfirmed = 0x11, // RSA 1024 is weak
pEp_ct_OpenPGP_unconfirmed = 0x3f, // key at least 2048 bit RSA
// or 1024 bit DSA
// range 0x40 to 0x7f: unconfirmed encryption and anonymization
pEp_ct_unconfirmed_enc_anon = 0x40, // generic
pEp_ct_pEp_unconfirmed = 0x7f,
pEp_ct_confirmed = 0x80, // this bit decides if trust is confirmed
// range 0x81 to 0x8f: reserved
// range 0x90 to 0xbf: confirmed encryption
pEp_ct_confirmed_encryption = 0x90, // generic
pEp_ct_OpenPGP_1024_RSA = 0x91, // RSA 1024 is weak
pEp_ct_OpenPGP = 0xbf, // key at least 2048 bit RSA or 1024 bit DSA
// range 0xc0 to 0xff: confirmed encryption and anonymization
pEp_ct_confirmed_enc_anon = 0xc0, // generic
pEp_ct_pEp = 0xff
} pEp_comm_type;
struct pEp_identity_s {
BSTR address;
BSTR fpr;
BSTR user_id;
BSTR username;
pEp_comm_type comm_type;
BSTR lang;
};
[id(8)] HRESULT get_identity([in] BSTR address, [out, retval] struct pEp_identity_s * ident);
[id(9)] HRESULT set_identity([in] struct pEp_identity_s * ident);
[id(10)] HRESULT generate_keypair([in] struct pEp_identity_s * ident, [out, retval] BSTR * fpr);
[id(11)] HRESULT delete_keypair([in] BSTR fpr);
[id(12)] HRESULT import_key([in] BSTR key_data);
[id(13)] HRESULT import_key_b([in] SAFEARRAY(BYTE) key_data);
[id(14)] HRESULT export_key([in] BSTR fpr, [out, retval] BSTR * key_data);
[id(15)] HRESULT recv_key([in] BSTR pattern);
[id(16)] HRESULT find_keys([in] BSTR pattern, [out, retval] SAFEARRAY(BSTR) * key_list);
[id(17)] HRESULT send_key([in] BSTR pattern);
[id(19)] HRESULT examine_identity([in] struct pEp_identity_s * ident);
[id(20)] HRESULT examine_myself([in] struct pEp_identity_s * myself);
[id(22)] HRESULT myself([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
[id(23)] HRESULT update_identity([in] struct pEp_identity_s *ident, [out, retval] struct pEp_identity_s *result);
};
[
uuid(3EC2E1A4-40E8-48E4-A7B0-1876D34F9462),
version(1.0),
]
library pEpCOMServerAdapterLib
{
importlib("stdole2.tlb");
[
uuid(B6BC9B8E-D9E2-4419-A3A4-7B4B58175549)
]
dispinterface _IpEpEngineEvents
{
properties:
methods:
};
[
uuid(EF1B073D-5058-4E0E-829E-B4D22CA21EA2)
]
coclass pEpEngine {
[default] interface IpEpEngine;
[default, source] dispinterface _IpEpEngineEvents;
};
};

BIN
pEpCOMServerAdapter.rc View File


+ 172
- 0
pEpCOMServerAdapter.vcxproj View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A27BD6BF-63BC-473D-B8BD-84ACB085F39C}</ProjectGuid>
<Keyword>AtlProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<TargetEnvironment>Win32</TargetEnvironment>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>pEpCOMServerAdapter_i.h</HeaderFileName>
<InterfaceIdentifierFileName>pEpCOMServerAdapter_i.c</InterfaceIdentifierFileName>
<ProxyFileName>pEpCOMServerAdapter_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)pEpCOMServerAdapter.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RegisterOutput>true</RegisterOutput>
<AdditionalDependencies>comsuppwd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<PerUserRedirection>true</PerUserRedirection>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<TargetEnvironment>Win32</TargetEnvironment>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>pEpCOMServerAdapter_i.h</HeaderFileName>
<InterfaceIdentifierFileName>pEpCOMServerAdapter_i.c</InterfaceIdentifierFileName>
<ProxyFileName>pEpCOMServerAdapter_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)pEpCOMServerAdapter.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<RegisterOutput>true</RegisterOutput>
<AdditionalDependencies>comsuppw.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CpEpEngine.cpp" />
<ClCompile Include="pEpCOMServerAdapter.cpp" />
<ClCompile Include="pEpCOMServerAdapter_i.c">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="utf8_helper.cpp" />
<ClCompile Include="xdlldata.c">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CpEpEngine.h" />
<ClInclude Include="locked_queue.hh" />
<ClInclude Include="pEpCOMServerAdapter_i.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="utf8_helper.h" />
<ClInclude Include="xdlldata.h" />
<ClInclude Include="_IpEpEngineEvents_CP.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="pEpCOMServerAdapter.rc" />
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<None Include="pEpCOMServerAdapter.rgs" />
<None Include="pEpEngine.rgs" />
</ItemGroup>
<ItemGroup>
<Midl Include="pEpCOMServerAdapter.idl" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\pEpEngine\pEpEngine.vcxproj">
<Project>{146e69f8-e1da-456a-b048-6dd29d9acf6b}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

+ 145
- 0
pEpComAdapter.idl View File

@ -0,0 +1,145 @@
// pEpComAdapter.idl : IDL source for pEpComAdapter
//
// This file will be processed by the MIDL tool to
// produce the type library (pEpComAdapter.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(9A9F4422-CF0A-45D7-90CD-1D1B7B2A4540),
oleautomation,
nonextensible,
pointer_default(unique)
]
interface IpEpEngine : IUnknown{
typedef enum _pEp_STATUS {
pEp_STATUS_OK = 0,
pEp_KEY_NOT_FOUND = 0x0201,
pEp_KEY_HAS_AMBIG_NAME = 0x0202,
pEp_GET_KEY_FAILED = 0x0203,
pEp_UNENCRYPTED = 0x0400,
pEp_VERIFIED = 0x0401,
pEp_DECRYPTED = 0x0402,
pEp_DECRYPTED_AND_VERIFIED = 0x0403,
pEp_DECRYPT_WRONG_FORMAT = 0x0404,
pEp_DECRYPT_NO_KEY = 0x0405,
pEp_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406,
pEp_VERIFY_NO_KEY = 0x0407,
pEp_VERIFIED_AND_TRUSTED = 0x0408,
pEp_ILLEGAL_VALUE = -4,
pEp_BUFFER_TOO_SMALL = -3,
pEp_OUT_OF_MEMORY = -2,
pEp_UNKNOWN_ERROR = -1
} pEp_STATUS;
[id(1)] HRESULT log([in] BSTR title, [in] BSTR entity, [in, defaultvalue("")] BSTR description, [in, defaultvalue("")] BSTR comment);
[id(2)] HRESULT decrypt([in] BSTR ctext, [out] BSTR * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
[id(3)] HRESULT decrypt_b([in] BSTR ctext, [out] SAFEARRAY(BYTE) * ptext, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * decrypt_status);
[id(4)] HRESULT encrypt([in] SAFEARRAY(BSTR) key_list, [in] BSTR ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
[id(5)] HRESULT encrypt_b([in] SAFEARRAY(BSTR) key_list, [in] SAFEARRAY(BYTE) ptext, [out] BSTR * ctext, [out, retval] pEp_STATUS * status);
[id(21)] HRESULT verify([in] BSTR text, [in] BSTR signature, [out] SAFEARRAY(BSTR) * key_list, [out, retval] pEp_STATUS * verify_status);
[id(6)] HRESULT safeword([in] LONG value, [in, defaultvalue("en")] BSTR lang, [out, retval] BSTR * word);
[id(7)] HRESULT safewords([in] BSTR fpr, [in, defaultvalue("en")] BSTR lang, [in, defaultvalue(0)] LONG max_words, [out, retval] BSTR * words);
typedef enum _pEp_comm_type {
pEp_ct_unknown = 0,
// range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable
pEp_ct_no_encryption = 0x01, // generic
pEp_ct_no_encrypted_channel = 0x02,
pEp_ct_key_not_found = 0x03,
pEp_ct_key_expired = 0x04,
pEp_ct_key_revoked = 0x05,
pEp_ct_key_b0rken = 0x06,
pEp_ct_my_key_not_included = 0x09,
pEp_ct_security_by_obscurity = 0x0a,
pEp_ct_b0rken_crypto = 0x0b,
pEp_ct_key_too_short = 0x0e,
pEp_ct_compromized = 0x0f, // known compromized connection