Compare commits

...

2 Commits

Author SHA1 Message Date
Volker Birk 72dbceb8c9 remove possible race condition 5 years ago
Volker Birk 114600ee17 synchronous API 5 years ago
  1. 2
      callback_dispatcher.cc
  2. 5
      callback_dispatcher.hh
  3. 7
      passphrase_cache.cc
  4. 7
      passphrase_cache.hh
  5. 30
      passphrase_cache.hxx

2
callback_dispatcher.cc

@ -80,8 +80,8 @@ namespace pEp {
void CallbackDispatcher::stop_sync() void CallbackDispatcher::stop_sync()
{ {
callback_dispatcher.semaphore.go();
pEp::Adapter::shutdown(); pEp::Adapter::shutdown();
callback_dispatcher.semaphore.go();
for (auto target : callback_dispatcher.targets) { for (auto target : callback_dispatcher.targets) {
if (target.notifyHandshake) if (target.notifyHandshake)

5
callback_dispatcher.hh

@ -5,9 +5,10 @@
#include <mutex> #include <mutex>
#include "Adapter.hh" #include "Adapter.hh"
#include "Semaphore.hh" #include "Semaphore.hh"
#include "passphrase_cache.hh"
namespace pEp { namespace pEp {
class PassphraseCache;
// use this class when implementing a desktop adapter // use this class when implementing a desktop adapter
// register different interfaces with add() // register different interfaces with add()
// then use CallbackDispatcher::start_sync() to start Sync // then use CallbackDispatcher::start_sync() to start Sync
@ -48,7 +49,7 @@ namespace pEp {
PEP_STATUS _notifyHandshake(::pEp_identity *me, PEP_STATUS _notifyHandshake(::pEp_identity *me,
::pEp_identity *partner, ::sync_handshake_signal signal); ::pEp_identity *partner, ::sync_handshake_signal signal);
friend const char *PassphraseCache::add(const std::string& passphrase); friend class PassphraseCache;
}; };
extern CallbackDispatcher callback_dispatcher; extern CallbackDispatcher callback_dispatcher;

7
passphrase_cache.cc

@ -1,9 +1,6 @@
#include <cassert> #include <cassert>
#include "Adapter.hh" #include "Adapter.hh"
#include "passphrase_cache.hh" #include "passphrase_cache.hh"
#include "callback_dispatcher.hh"
pEp::PassphraseCache pEp::passphrase_cache;
namespace pEp { namespace pEp {
PassphraseCache::cache_entry::cache_entry(const std::string& p, time_point t) : PassphraseCache::cache_entry::cache_entry(const std::string& p, time_point t) :
@ -12,13 +9,13 @@ namespace pEp {
PassphraseCache::PassphraseCache(size_t max_size, duration timeout) : PassphraseCache::PassphraseCache(size_t max_size, duration timeout) :
_max_size{max_size}, _timeout{timeout}, _which(_cache.end()), _max_size{max_size}, _timeout{timeout}, _which(_cache.end()),
first_time(true) first_time(true), synchronous(false)
{ } { }
PassphraseCache::PassphraseCache(const PassphraseCache& second) : PassphraseCache::PassphraseCache(const PassphraseCache& second) :
_cache{second._cache}, _max_size{second._max_size}, _cache{second._cache}, _max_size{second._max_size},
_timeout{second._timeout}, _stored{second._stored}, _timeout{second._timeout}, _stored{second._stored},
_which(_cache.end()), first_time(true) _which(_cache.end()), first_time(true), synchronous(false)
{ {
cleanup(); cleanup();
} }

7
passphrase_cache.hh

@ -8,6 +8,8 @@
#include <exception> #include <exception>
#include <pEp/message_api.h> #include <pEp/message_api.h>
#include "callback_dispatcher.hh"
namespace pEp { namespace pEp {
class PassphraseCache { class PassphraseCache {
using clock = std::chrono::system_clock; using clock = std::chrono::system_clock;
@ -33,6 +35,8 @@ namespace pEp {
cache::iterator _which; cache::iterator _which;
bool first_time; bool first_time;
bool synchronous;
public: public:
struct Empty : public std::underflow_error { struct Empty : public std::underflow_error {
Empty() : std::underflow_error("passphrase cache empty") { } Empty() : std::underflow_error("passphrase cache empty") { }
@ -46,6 +50,9 @@ namespace pEp {
PassphraseCache(const PassphraseCache& second); PassphraseCache(const PassphraseCache& second);
PassphraseCache& operator=(const PassphraseCache& second); PassphraseCache& operator=(const PassphraseCache& second);
// switch this on for synchronous API
void config_synchronous_api(bool enable = true) { synchronous = enable; }
// adds the passphrase to the cache, which will timeout // adds the passphrase to the cache, which will timeout
// returns a ptr to the passsword entry in the cache. Don't free() it! // returns a ptr to the passsword entry in the cache. Don't free() it!
const char *add(const std::string& passphrase); const char *add(const std::string& passphrase);

30
passphrase_cache.hxx

@ -1,21 +1,33 @@
#pragma once
#include "passphrase_cache.hh" #include "passphrase_cache.hh"
extern pEp::CallbackDispatcher callback_dispatcher;
namespace pEp { namespace pEp {
template<typename... A> PEP_STATUS PassphraseCache::api( template<typename... A> PEP_STATUS PassphraseCache::api(
PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a)
{ {
PEP_STATUS status; PEP_STATUS status;
for_each_passphrase([&](std::string passphrase) { do {
status = ::config_passphrase(session, passphrase.c_str()); if (synchronous) {
if (status) callback_dispatcher.semaphore.try_wait();
return true; }
for_each_passphrase([&](std::string passphrase) {
status = ::config_passphrase(session, passphrase.c_str());
if (status)
return true;
status = f(session, a...);
return status != PEP_PASSPHRASE_REQUIRED &&
status != PEP_WRONG_PASSPHRASE;
});
status = f(session, a...); if (synchronous) {
return status != PEP_PASSPHRASE_REQUIRED && CallbackDispatcher::notifyHandshake(nullptr, nullptr, SYNC_PASSPHRASE_REQUIRED);
status != PEP_WRONG_PASSPHRASE; callback_dispatcher.semaphore.stop();
}); }
} while (synchronous);
return status; return status;
} }

Loading…
Cancel
Save