C++11 library providing functionality common to all adapters.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.9 KiB

#pragma once
#include <list>
#include <string>
#include <chrono>
#include <mutex>
#include <functional>
#include <exception>
#include <pEp/message_api.h>
namespace pEp {
class PassphraseCache {
using clock = std::chrono::system_clock;
using time_point = std::chrono::time_point<clock>;
using duration = clock::duration;
struct cache_entry {
static const size_t max_len = 250 * 4;
cache_entry(const std::string& p, time_point t);
std::string passphrase;
time_point tp;
using cache = std::list<cache_entry>;
cache _cache;
std::string _stored;
std::mutex _mtx;
std::mutex _stored_mtx;
size_t _max_size;
duration _timeout;
cache::iterator _which;
bool first_time;
struct Empty : public std::underflow_error {
Empty() : std::underflow_error("passphrase cache empty") { }
struct Exhausted : public std::underflow_error {
Exhausted() : std::underflow_error("out of passphrases") { }
PassphraseCache(size_t max_size=20, duration timeout = std::chrono::minutes(10));
~PassphraseCache() { }
PassphraseCache(const PassphraseCache& second);
PassphraseCache& operator=(const PassphraseCache& second);
// 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);
// adds the stored passphrase to the cache, which will not timeout
const char *add_stored(const std::string& passphrase);
// call this function inside the messageToSend() implementation of the adapter
// this function is using latest_passphrase() to test one passphrase after the
// other until the cache is exhausted
// call with reset = true to reset the iterator
static PEP_STATUS config_next_passphrase(bool reset=false, PEP_SESSION session = NULL);
// convenience functions
// i.e.
// status = cache.api(::encrypt_message, session, src, extra, dst, enc_format, flags)
// will call
// status = ::encrypt_message(session, src, extra, dst, enc_format, flags)
// using for_each_passphrase()
template<typename... A> PEP_STATUS api(PEP_STATUS f(PEP_SESSION, A...),
PEP_SESSION session, A... a);
static const char *latest_passphrase(PassphraseCache& _cache);
using passphrase_callee = std::function<bool(std::string)>;
bool for_each_passphrase(const passphrase_callee& callee);
PEP_STATUS ensure_passphrase(PEP_SESSION session, std::string fpr);
void cleanup();
void refresh(cache::iterator entry);
extern PassphraseCache passphrase_cache;
#include "passphrase_cache.hxx"