diff --git a/callback_dispatcher.hh b/callback_dispatcher.hh index 17f39e3..079e56e 100644 --- a/callback_dispatcher.hh +++ b/callback_dispatcher.hh @@ -5,9 +5,10 @@ #include #include "Adapter.hh" #include "Semaphore.hh" -#include "passphrase_cache.hh" namespace pEp { + class PassphraseCache; + // use this class when implementing a desktop adapter // register different interfaces with add() // then use CallbackDispatcher::start_sync() to start Sync @@ -48,7 +49,7 @@ namespace pEp { PEP_STATUS _notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal); - friend const char *PassphraseCache::add(const std::string& passphrase); + friend class PassphraseCache; }; extern CallbackDispatcher callback_dispatcher; diff --git a/passphrase_cache.cc b/passphrase_cache.cc index 45e10b1..6112850 100644 --- a/passphrase_cache.cc +++ b/passphrase_cache.cc @@ -1,9 +1,6 @@ #include #include "Adapter.hh" #include "passphrase_cache.hh" -#include "callback_dispatcher.hh" - -pEp::PassphraseCache pEp::passphrase_cache; namespace pEp { 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) : _max_size{max_size}, _timeout{timeout}, _which(_cache.end()), - first_time(true) + first_time(true), synchronous(false) { } PassphraseCache::PassphraseCache(const PassphraseCache& second) : _cache{second._cache}, _max_size{second._max_size}, _timeout{second._timeout}, _stored{second._stored}, - _which(_cache.end()), first_time(true) + _which(_cache.end()), first_time(true), synchronous(false) { cleanup(); } diff --git a/passphrase_cache.hh b/passphrase_cache.hh index 205d1ea..8bb4625 100644 --- a/passphrase_cache.hh +++ b/passphrase_cache.hh @@ -8,6 +8,8 @@ #include #include +#include "callback_dispatcher.hh" + namespace pEp { class PassphraseCache { using clock = std::chrono::system_clock; @@ -33,6 +35,8 @@ namespace pEp { cache::iterator _which; bool first_time; + bool synchronous; + public: struct Empty : public std::underflow_error { Empty() : std::underflow_error("passphrase cache empty") { } @@ -46,6 +50,9 @@ namespace pEp { PassphraseCache(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 // returns a ptr to the passsword entry in the cache. Don't free() it! const char *add(const std::string& passphrase); diff --git a/passphrase_cache.hxx b/passphrase_cache.hxx index 17d9288..2af3750 100644 --- a/passphrase_cache.hxx +++ b/passphrase_cache.hxx @@ -1,21 +1,33 @@ -#pragma once #include "passphrase_cache.hh" +extern pEp::CallbackDispatcher callback_dispatcher; + namespace pEp { template PEP_STATUS PassphraseCache::api( PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) { PEP_STATUS status; - for_each_passphrase([&](std::string passphrase) { - status = ::config_passphrase(session, passphrase.c_str()); - if (status) - return true; + do { + if (synchronous) { + callback_dispatcher.semaphore.try_wait(); + } + + 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...); - return status != PEP_PASSPHRASE_REQUIRED && - status != PEP_WRONG_PASSPHRASE; - }); + if (synchronous) { + CallbackDispatcher::notifyHandshake(nullptr, nullptr, SYNC_PASSPHRASE_REQUIRED); + callback_dispatcher.semaphore.stop(); + } + } while (synchronous); return status; }