[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [ksecrets] src/runtime/ksecrets_store: Introducting persistance logic base
From: Valentin Rusu <kde () rusu ! info>
Date: 2015-08-18 22:40:45
Message-ID: E1ZRpYj-0003om-0M () scm ! kde ! org
[Download RAW message or body]
Git commit 1167bb267d28d40e150a4c788891fc5218e4a4c9 by Valentin Rusu.
Committed on 18/08/2015 at 22:40.
Pushed by vrusu into branch 'master'.
Introducting persistance logic base
M +30 -64 src/runtime/ksecrets_store/ksecrets_crypt.cpp
M +2 -1 src/runtime/ksecrets_store/ksecrets_crypt.h
M +108 -23 src/runtime/ksecrets_store/ksecrets_data.cpp
M +63 -7 src/runtime/ksecrets_store/ksecrets_data.h
M +25 -0 src/runtime/ksecrets_store/ksecrets_file.cpp
M +7 -2 src/runtime/ksecrets_store/ksecrets_file.h
M +38 -0 src/runtime/ksecrets_store/ksecrets_store.cpp
M +12 -5 src/runtime/ksecrets_store/ksecrets_store.h
M +4 -0 src/runtime/ksecrets_store/ksecrets_store_p.h
http://commits.kde.org/ksecrets/1167bb267d28d40e150a4c788891fc5218e4a4c9
diff --git a/src/runtime/ksecrets_store/ksecrets_crypt.cpp \
b/src/runtime/ksecrets_store/ksecrets_crypt.cpp index a5a32f8..2b25867 100644
--- a/src/runtime/ksecrets_store/ksecrets_crypt.cpp
+++ b/src/runtime/ksecrets_store/ksecrets_crypt.cpp
@@ -52,8 +52,7 @@ int kss_init_gcry()
gcry_error_t gcryerr;
gcryerr = gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0);
if (gcryerr != 0) {
- syslog(KSS_LOG_ERR, "ksecrets_store: cannot get secure memory: %d",
- gcryerr);
+ syslog(KSS_LOG_ERR, "ksecrets_store: cannot get secure memory: %d", gcryerr);
return 0;
}
@@ -62,44 +61,36 @@ int kss_init_gcry()
return 1;
}
-int kss_derive_keys(const char* salt, const char* password,
- char* encryption_key, char* mac_key, size_t keySize)
+int kss_derive_keys(const char* salt, const char* password, char* encryption_key, char* \
mac_key, size_t keySize) {
gpg_error_t gcryerr;
syslog(KSS_LOG_INFO, "kss_set_credentials: attempting keys generation");
if (0 == password) {
- syslog(KSS_LOG_INFO,
- "NULL password given. ksecrets will not be available.");
+ syslog(KSS_LOG_INFO, "NULL password given. ksecrets will not be available.");
return FALSE;
}
/* generate both encryption and MAC key in one go */
char keys[2 * keySize];
- gcryerr
- = gcry_kdf_derive(password, strlen(password), GCRY_KDF_ITERSALTED_S2K,
- GCRY_MD_SHA512, salt, 8, KSECRETS_ITERATIONS, 2 * keySize, keys);
+ gcryerr = gcry_kdf_derive(password, strlen(password), GCRY_KDF_ITERSALTED_S2K, \
GCRY_MD_SHA512, salt, 8, KSECRETS_ITERATIONS, 2 * keySize, keys); if (gcryerr) {
- syslog(KSS_LOG_ERR, "key derivation failed: code 0x%0x: %s/%s",
- gcryerr, gcry_strsource(gcryerr), gcry_strerror(gcryerr));
+ syslog(KSS_LOG_ERR, "key derivation failed: code 0x%0x: %s/%s", gcryerr, \
gcry_strsource(gcryerr), gcry_strerror(gcryerr)); return FALSE;
}
memcpy(encryption_key, keys, keySize);
memcpy(mac_key, keys + keySize, keySize);
- syslog(KSS_LOG_INFO,
- "successuflly generated ksecrets keys from user password.");
+ syslog(KSS_LOG_INFO, "successuflly generated ksecrets keys from user password.");
return TRUE;
}
-int kss_store_keys(
- const char* encryption_key, const char* mac_key, size_t keySize)
+int kss_store_keys(const char* encryption_key, const char* mac_key, size_t keySize)
{
key_serial_t ks;
const char* key_name = get_keyname_encrypting();
- ks = add_key(
- "user", key_name, encryption_key, keySize, KEY_SPEC_SESSION_KEYRING);
+ ks = add_key("user", key_name, encryption_key, keySize, KEY_SPEC_SESSION_KEYRING);
if (-1 == ks) {
syslog(KSS_LOG_ERR, "ksecrets: cannot store encryption key in kernel "
"keyring: errno=%d (%m)",
@@ -111,17 +102,12 @@ int kss_store_keys(
ks, key_name);
key_name = get_keyname_mac();
- ks = add_key(
- "user", key_name, mac_key, keySize, KEY_SPEC_SESSION_KEYRING);
+ ks = add_key("user", key_name, mac_key, keySize, KEY_SPEC_SESSION_KEYRING);
if (-1 == ks) {
- syslog(KSS_LOG_ERR,
- "ksecrets: cannot store mac key in kernel keyring: errno=%d (%m)",
- errno);
+ syslog(KSS_LOG_ERR, "ksecrets: cannot store mac key in kernel keyring: errno=%d (%m)", \
errno); return FALSE;
}
- syslog(KSS_LOG_DEBUG,
- "ksecrets: mac key now in kernel keyring with id %d and desc %s", ks,
- key_name);
+ syslog(KSS_LOG_DEBUG, "ksecrets: mac key now in kernel keyring with id %d and desc %s", \
ks, key_name); return TRUE;
}
@@ -131,8 +117,7 @@ int kss_set_credentials(const std::string& password, const char* salt)
// available and store the keys elsewhere
char encryption_key[KSECRETS_KEYSIZE];
char mac_key[KSECRETS_KEYSIZE];
- auto res = kss_derive_keys(
- salt, password.c_str(), encryption_key, mac_key, KSECRETS_KEYSIZE);
+ auto res = kss_derive_keys(salt, password.c_str(), encryption_key, mac_key, \
KSECRETS_KEYSIZE); if (res)
return res;
@@ -142,8 +127,7 @@ int kss_set_credentials(const std::string& password, const char* salt)
int kss_keys_already_there()
{
key_serial_t key;
- key = request_key(
- "user", get_keyname_encrypting(), 0, KEY_SPEC_SESSION_KEYRING);
+ key = request_key("user", get_keyname_encrypting(), 0, KEY_SPEC_SESSION_KEYRING);
if (-1 == key) {
syslog(KSS_LOG_DEBUG, "request_key failed with errno %d (%m), so "
"assuming ksecrets not yet loaded",
@@ -159,15 +143,12 @@ long kss_read_key(const char* keyName, char* buffer, size_t bufferSize)
key_serial_t key;
key = request_key("user", keyName, 0, KEY_SPEC_SESSION_KEYRING);
if (-1 == key) {
- syslog(KSS_LOG_DEBUG,
- "request_key failed with errno %d (%m) when reading MAC key %s",
- errno, keyName);
+ syslog(KSS_LOG_DEBUG, "request_key failed with errno %d (%m) when reading MAC key %s", \
errno, keyName); return -1;
}
auto bytes = keyctl_read(key, buffer, bufferSize);
if (bytes == -1) {
- syslog(KSS_LOG_ERR, "error reading key %s contents from the keyring",
- keyName);
+ syslog(KSS_LOG_ERR, "error reading key %s contents from the keyring", keyName);
return -1;
}
if ((size_t)bytes > bufferSize) {
@@ -176,15 +157,9 @@ long kss_read_key(const char* keyName, char* buffer, size_t bufferSize)
return 0; // key contents correctly transffered into the buffer
}
-long kss_read_mac_key(char* buffer, size_t bufferSize)
-{
- return kss_read_key(get_keyname_mac(), buffer, bufferSize);
-}
+long kss_read_mac_key(char* buffer, size_t bufferSize) { return \
kss_read_key(get_keyname_mac(), buffer, bufferSize); }
-long kss_read_encrypting_key(char* buffer, size_t bufferSize)
-{
- return kss_read_key(get_keyname_encrypting(), buffer, bufferSize);
-}
+long kss_read_encrypting_key(char* buffer, size_t bufferSize) { return \
kss_read_key(get_keyname_encrypting(), buffer, bufferSize); }
#define ERRNO(cryres) gcry_err_code_to_errno(gcry_err_code(cryres))
@@ -192,39 +167,31 @@ long kss_cipher_setup(gcry_cipher_hd_t* hd, const void* iv, size_t liv)
{
// FIXME perhaps all this initialization stuff could only be done once,
// when password is setup
- auto cryres
- = gcry_cipher_open(hd, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 0);
+ auto cryres = gcry_cipher_open(hd, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 0);
if (cryres) {
- syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_open returned error %d",
- cryres);
+ syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_open returned error %d", cryres);
return ERRNO(cryres);
}
cryres = gcry_cipher_setiv(*hd, iv, liv);
if (cryres) {
- syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_setif returned error %d",
- cryres);
+ syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_setif returned error %d", cryres);
return ERRNO(cryres);
}
char encryptingKey[KSECRETS_KEYSIZE];
- auto keyres = kss_read_encrypting_key(
- encryptingKey, sizeof(encryptingKey) / sizeof(encryptingKey[0]));
+ auto keyres = kss_read_encrypting_key(encryptingKey, sizeof(encryptingKey) / \
sizeof(encryptingKey[0])); if (!keyres) {
- syslog(
- KSS_LOG_ERR, "ksecrets: encrypting key not found in the keyring");
+ syslog(KSS_LOG_ERR, "ksecrets: encrypting key not found in the keyring");
return keyres;
}
- cryres = gcry_cipher_setkey(
- *hd, encryptingKey, sizeof(encryptingKey) / sizeof(encryptingKey[0]));
+ cryres = gcry_cipher_setkey(*hd, encryptingKey, sizeof(encryptingKey) / \
sizeof(encryptingKey[0])); if (cryres) {
- syslog(
- KSS_LOG_ERR, "ksecrets: gcry_cipher_setkey returned %d", cryres);
+ syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_setkey returned %d", cryres);
return ERRNO(cryres);
}
return 0;
}
-long kss_encrypt_buffer(unsigned char* out, size_t lout, const void* iv,
- size_t liv, const unsigned char* in, size_t lin)
+long kss_encrypt_buffer(unsigned char* out, size_t lout, const void* iv, size_t liv, const \
unsigned char* in, size_t lin) {
gcry_cipher_hd_t hd;
auto cryres = kss_cipher_setup(&hd, iv, liv);
@@ -232,15 +199,13 @@ long kss_encrypt_buffer(unsigned char* out, size_t lout, const void* iv,
return cryres; // error already logged
cryres = gcry_cipher_encrypt(hd, out, lout, in, lin);
if (cryres) {
- syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_encrypt returned %ld",
- cryres);
+ syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_encrypt returned %ld", cryres);
return ERRNO(cryres);
}
return 0;
}
-long kss_decrypt_buffer(unsigned char* out, size_t lout, const void* iv,
- size_t liv, const unsigned char* in, size_t lin)
+long kss_decrypt_buffer(unsigned char* out, size_t lout, const void* iv, size_t liv, const \
unsigned char* in, size_t lin) {
gcry_cipher_hd_t hd;
auto cryres = kss_cipher_setup(&hd, iv, liv);
@@ -248,13 +213,14 @@ long kss_decrypt_buffer(unsigned char* out, size_t lout, const void* iv,
return cryres; // error already logged
cryres = gcry_cipher_decrypt(hd, out, lout, in, lin);
if (cryres) {
- syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_decrypt returned %ld",
- cryres);
+ syslog(KSS_LOG_ERR, "ksecrets: gcry_cipher_decrypt returned %ld", cryres);
return ERRNO(cryres);
}
return 0;
}
+CryptBuffer::~CryptBuffer() { delete[] data_; }
+
bool CryptBuffer::resize(size_t rlen)
{
if (rlen <= len_) {
diff --git a/src/runtime/ksecrets_store/ksecrets_crypt.h \
b/src/runtime/ksecrets_store/ksecrets_crypt.h index 86e1788..742e42e 100644
--- a/src/runtime/ksecrets_store/ksecrets_crypt.h
+++ b/src/runtime/ksecrets_store/ksecrets_crypt.h
@@ -29,7 +29,8 @@ struct CryptBuffer {
, data_(nullptr)
{
}
- ~CryptBuffer() { delete[] data_; }
+ CryptBuffer(CryptBuffer&&) = default;
+ ~CryptBuffer();
/**
* @brief Allocate memory in multiples of cipher block len
diff --git a/src/runtime/ksecrets_store/ksecrets_data.cpp \
b/src/runtime/ksecrets_store/ksecrets_data.cpp index 61a8f64..7c9aa81 100644
--- a/src/runtime/ksecrets_store/ksecrets_data.cpp
+++ b/src/runtime/ksecrets_store/ksecrets_data.cpp
@@ -22,11 +22,11 @@
#include "ksecrets_file.h"
#include <unistd.h>
+#include <algorithm>
+#include <cassert>
-long kss_encrypt_buffer(unsigned char* out, size_t lout, const void* iv,
- size_t liv, const unsigned char* in, size_t lin);
-long kss_decrypt_buffer(unsigned char* out, size_t lout, const void* iv,
- size_t liv, const unsigned char* in, size_t lin);
+long kss_encrypt_buffer(unsigned char* out, size_t lout, const void* iv, size_t liv, const \
unsigned char* in, size_t lin); +long kss_decrypt_buffer(unsigned char* out, size_t lout, const \
void* iv, size_t liv, const unsigned char* in, size_t lin); char* \
kss_alloc_crypt_buffer(size_t rlen);
SecretsEntity::SecretsEntity()
@@ -42,47 +42,132 @@ SecretsEntity::~SecretsEntity() {}
const char* iv = nullptr;
size_t liv = KSecretsFile::IV_SIZE;
+bool SecretsEntity::decrypt()
+{
+ if (isEmpty())
+ return false;
+ if (unencrypted_.len_ > 0)
+ return true; // already decrpyted
+ if (encrypted_.len_ == 0)
+ return false; // what to decrypt?
+ unencrypted_.allocate(encrypted_.len_);
+ auto dres = kss_decrypt_buffer(unencrypted_.data_, unencrypted_.len_, iv, liv, \
encrypted_.data_, encrypted_.len_); + return dres == 0;
+}
+
+bool SecretsEntity::encrypt()
+{
+ // TODO
+ return false;
+}
+
+bool SecretsEntity::write(KSecretsFile& file)
+{
+ bool res = false;
+ if (doBeforeWrite()) {
+ if (encrypt()) {
+ assert(state_ == State::Encrypted);
+ if (file.write(encrypted_.len_)) {
+ if (encrypted_.len_ > 0) {
+ assert(encrypted_.data_ != nullptr);
+ if (file.write(encrypted_.data_, encrypted_.len_)) {
+ res = true;
+ }
+ }
+ else {
+ res = true;
+ }
+ }
+ }
+ }
+ if (res)
+ return doAfterWrite();
+ else
+ return res;
+}
+
bool SecretsEntity::read(KSecretsFile& file)
{
if (iv == nullptr) {
iv = file.iv();
}
+ if (!doBeforeRead())
+ return false;
- size_t s;
- if (!file.read(s)) {
+ encrypted_.empty();
+ size_t len;
+ if (!file.read(len))
return false;
- }
- if (!encrypted_.allocate(s)) {
+
+ if (!encrypted_.allocate(len))
return false;
+
+ if (len > 0) {
+ if (!file.read(encrypted_.data_, encrypted_.len_))
+ return false;
}
- return file.read(encrypted_.data_,
- encrypted_.len_); // beware not to specify encrypted.size_ here
+ return doAfterRead();
}
-bool SecretsEntity::decrypt()
+CollectionDirectory::CollectionDirectory()
{
- if (isEmpty())
- return false;
- if (unencrypted_.len_ > 0)
- return true; // already decrpyted
- if (encrypted_.len_ == 0)
- return false; // what to decrypt?
- unencrypted_.allocate(encrypted_.len_);
- auto dres = kss_decrypt_buffer(unencrypted_.data_, unencrypted_.len_, iv,
- liv, encrypted_.data_, encrypted_.len_);
- return dres == 0;
}
-bool SecretsEntity::encrypt()
+bool CollectionDirectory::hasEntry(const std::string& collName) const
+{
+ auto pos = std::find(entries_.begin(), entries_.end(), collName);
+ return pos != entries_.end();
+}
+
+bool CollectionDirectory::doBeforeWrite()
+{
+ // TODO
+ return false;
+}
+
+bool CollectionDirectory::doAfterRead()
+{
+ // TODO
+ return false;
+}
+
+void SecretsCollection::setName(const std::string& name) { name_ = name; }
+
+bool SecretsCollection::doBeforeWrite()
{
// TODO
return false;
}
-bool SecretsEntity::write(KSecretsFile &) const
+bool SecretsCollection::doAfterRead()
{
// TODO
return false;
}
+
+bool SecretsItem::doBeforeWrite()
+{
+ // TODO
+ return false;
+}
+
+bool SecretsItem::doAfterRead()
+{
+ // TODO
+ return false;
+}
+
+bool SecretsEOF::doBeforeWrite()
+{
+ // TODO
+ return false;
+}
+
+bool SecretsEOF::doAfterRead()
+{
+ // TODO
+ return false;
+}
+
// vim: tw=220:ts=4
diff --git a/src/runtime/ksecrets_store/ksecrets_data.h \
b/src/runtime/ksecrets_store/ksecrets_data.h index dca51f7..a233c41 100644
--- a/src/runtime/ksecrets_store/ksecrets_data.h
+++ b/src/runtime/ksecrets_store/ksecrets_data.h
@@ -25,6 +25,8 @@
#include <cstdint>
#include <sys/types.h>
+#include <memory>
+#include <list>
class KSecretsFile;
@@ -34,11 +36,17 @@ class KSecretsFile;
* TODO this class uses routines from ksecrets_crypt.cpp file to handle
* encrypting and decrypting of the files. It would be better to define some
* plugin architecture, allowing users specify different encryption methods.
+ *
+ * TODO in the future, if the need arises to add another file format, this
+ *code
+ * could be easily refactored to use the "visitor" pattern and convert the
+ * read and write methods to use a generic type which would then be
+ * implemented by the KSecretsFile. For now, no need of such generalization,
+ * as I cannot foresee the introduction of another file format (why should I?)
*/
-struct SecretsEntity {
+class SecretsEntity {
+public:
SecretsEntity();
- SecretsEntity(const SecretsEntity&) = delete;
- SecretsEntity(SecretsEntity&&) = delete;
virtual ~SecretsEntity();
enum class State : std::uint8_t {
@@ -48,6 +56,7 @@ struct SecretsEntity {
};
bool isEmpty() const noexcept { return state_ == State::Empty; }
+ virtual bool hasNext() const noexcept { return true; }
bool isDecrypted() const noexcept
{
return (static_cast<std::uint8_t>(state_)
@@ -57,18 +66,65 @@ struct SecretsEntity {
virtual bool decrypt() noexcept;
virtual bool encrypt() noexcept;
- virtual bool read(KSecretsFile&) noexcept;
- virtual bool write(KSecretsFile&) const noexcept;
+ bool read(KSecretsFile&) noexcept;
+ virtual bool doBeforeRead() noexcept { return true; }
+ virtual bool doAfterRead() noexcept = 0;
+
+ bool write(KSecretsFile&) noexcept;
+ virtual bool doBeforeWrite() noexcept = 0;
+ virtual bool doAfterWrite() noexcept { return true; }
State state_;
CryptBuffer encrypted_;
CryptBuffer unencrypted_;
};
-struct SecretsCollection : public SecretsEntity {
+using SecretsEntityPtr = std::shared_ptr<SecretsEntity>;
+
+class SecretsCollection : public SecretsEntity {
+public:
+ void setName(const std::string&) noexcept;
+
+private:
+ virtual bool doBeforeWrite() noexcept override;
+ virtual bool doAfterRead() noexcept override;
+
+ std::string name_;
};
-struct CollectionDirectory : public SecretsEntity {
+using SecretsCollectionPtr = std::shared_ptr<SecretsCollection>;
+
+class CollectionDirectory : public SecretsEntity {
+public:
+ CollectionDirectory();
+ bool hasEntry(const std::string&) const noexcept;
+
+private:
+ virtual bool doBeforeWrite() noexcept override;
+ virtual bool doAfterRead() noexcept override;
+
+ std::list<std::string> entries_;
};
+using CollectionDirectoryPtr = std::shared_ptr<CollectionDirectory>;
+
+class SecretsItem : public SecretsEntity {
+public:
+private:
+ virtual bool doBeforeWrite() noexcept override;
+ virtual bool doAfterRead() noexcept override;
+};
+
+using SecretsItemPtr = std::shared_ptr<SecretsItem>;
+
+class SecretsEOF : public SecretsEntity {
+private:
+ bool hasNext() const noexcept override { return false; }
+ virtual bool doBeforeWrite() noexcept override;
+ virtual bool doAfterRead() noexcept override;
+};
+
+using SecretsEOFPtr = std::shared_ptr<SecretsEOF>;
+
#endif
+// vim: tw=220:ts=4
diff --git a/src/runtime/ksecrets_store/ksecrets_file.cpp \
b/src/runtime/ksecrets_store/ksecrets_file.cpp index c3dc275..2fc075b 100644
--- a/src/runtime/ksecrets_store/ksecrets_file.cpp
+++ b/src/runtime/ksecrets_store/ksecrets_file.cpp
@@ -141,6 +141,23 @@ int KSecretsFile::checkMAC() const
return -1;
}
+bool KSecretsFile::write(size_t s) { return write(&s, sizeof(size_t)); }
+
+bool KSecretsFile::write(const void* buf, size_t len)
+{
+ auto wres = ::write(file_, buf, len);
+ if (wres <0) {
+ return setFailState(errno);
+ }
+ if (static_cast<size_t>(wres) < len) {
+ // no more space left on the file system
+ // FIXME we should prevent such an event by keeping versions of the secrets file
+ // TODO manage secrets file versions to prevent this kind of problem
+ return setFailState(ENOSPC);
+ }
+ return true;
+}
+
bool KSecretsFile::read(size_t& s) { return read(&s, sizeof(s)); }
bool KSecretsFile::read(void* buf, size_t len)
@@ -184,4 +201,12 @@ bool KSecretsFile::readDirectory()
bool KSecretsFile::decryptEntity(SecretsEntity& entity) { return entity.decrypt(); }
+SecretsCollectionPtr KSecretsFile::createCollection(const std::string &collName) noexcept
+{
+ auto newColl = std::make_shared<SecretsCollection>();
+ newColl->setName(collName);
+ entities_.emplace_front(newColl);
+ return std::dynamic_pointer_cast<SecretsCollection>(entities_.front());
+}
+
// vim: tw=220:ts=4
diff --git a/src/runtime/ksecrets_store/ksecrets_file.h \
b/src/runtime/ksecrets_store/ksecrets_file.h index 5ed8c79..3c9b2e7 100644
--- a/src/runtime/ksecrets_store/ksecrets_file.h
+++ b/src/runtime/ksecrets_store/ksecrets_file.h
@@ -24,7 +24,7 @@
#include "ksecrets_data.h"
#include <memory>
-#include <list>
+#include <forward_list>
/**
* @brief This is the secrets file format handling class
@@ -53,9 +53,14 @@ public:
int checkMAC() const noexcept;
bool read(void* buf, size_t count);
bool read(size_t&);
+ int errnumber() const noexcept { return errno_; }
+ bool eof() const noexcept { return eof_; }
+ bool write(const void *buf, size_t count);
+ bool write(size_t len);
using DirCollectionResult = std::pair<bool, const CollectionDirectory*>;
DirCollectionResult dirCollections() noexcept;
+ SecretsCollectionPtr createCollection(const std::string &collName) noexcept;
private:
bool setFailState(int err, bool retval = false) noexcept
@@ -70,7 +75,7 @@ private:
bool readDirectory() noexcept;
bool decryptEntity(SecretsEntity&) noexcept;
- using Entities = std::list<SecretsEntity*>;
+ using Entities = std::forward_list<SecretsEntityPtr>;
std::string filePath_;
int file_;
diff --git a/src/runtime/ksecrets_store/ksecrets_store.cpp \
b/src/runtime/ksecrets_store/ksecrets_store.cpp index 8e4bf00..b88b83d 100644
--- a/src/runtime/ksecrets_store/ksecrets_store.cpp
+++ b/src/runtime/ksecrets_store/ksecrets_store.cpp
@@ -170,13 +170,51 @@ KSecretsStore::CreateCollectionResult \
KSecretsStore::createCollection(const char return d->createCollection(collName);
}
+template <class R>
+R mapSecretsFileFailure(KSecretsFile &file, R &&r)
+{
+ if (file.errnumber()) {
+ r.errno_ = file.errnumber();
+ r.status_ = KSecretsStore::StoreStatus::SystemError;
+ } else {
+ if (file.eof()) {
+ r.status_ = KSecretsStore::StoreStatus::PrematureEndOfFileEncountered;
+ } else {
+ r.status_ = KSecretsStore::StoreStatus::UnknownError; // really, we should get \
here very seldom + }
+ }
+
+ return r;
+}
+
KSecretsStore::CreateCollectionResult KSecretsStorePrivate::createCollection(const std::string \
&collName) noexcept {
KSecretsStore::CreateCollectionResult res;
+ auto cptr = std::make_shared<KSecretsCollectionPrivate>();
+ if (!cptr->createCollection(secretsFile_, collName)) {
+ return mapSecretsFileFailure(secretsFile_, res);
+ }
+ res.result_ = std::make_shared<KSecretsStore::Collection>(cptr);
+ return res;
+}
+bool KSecretsCollectionPrivate::createCollection(KSecretsFile &file, const std::string \
&collName) +{
+ bool res = false;
+ auto dir = file.dirCollections();
+ if (dir.first) {
+ if (!dir.second->hasEntry(collName)) {
+ collection_data_ = file.createCollection(collName);
+ if (collection_data_ != nullptr) {
+ res = true;
+ }
+ }
+ }
return res;
}
+KSecretsStore::Collection::Collection(KSecretsCollectionPrivatePtr dptr) : d(dptr) {}
+
KSecretsStore::ReadCollectionResult KSecretsStore::readCollection(const char*) const noexcept
{
// TODO
diff --git a/src/runtime/ksecrets_store/ksecrets_store.h \
b/src/runtime/ksecrets_store/ksecrets_store.h index 6b899b0..136b0c1 100644
--- a/src/runtime/ksecrets_store/ksecrets_store.h
+++ b/src/runtime/ksecrets_store/ksecrets_store.h
@@ -31,6 +31,12 @@
#include <future>
class KSecretsStorePrivate;
+class KSecretsItemPrivate;
+class KSecretsCollectionPrivate;
+
+using KSecretsItemPrivatePtr = std::shared_ptr<KSecretsItemPrivate>;
+using KSecretsCollectionPrivatePtr = std::shared_ptr<KSecretsCollectionPrivate>;
+
/**
* Secrets storage for KSecrets Service.
@@ -72,9 +78,6 @@ class KSecretsStorePrivate;
* would be destroyed, releasing the file, upon block exit.
*/
class KSECRETS_STORE_EXPORT KSecretsStore {
- class ItemPrivate;
- class CollectionPrivate;
-
public:
using AttributesMap = std::map<std::string, std::string>;
@@ -122,7 +125,7 @@ public:
friend class KSecretsStore;
private:
- std::shared_ptr<ItemPrivate> d;
+ KSecretsItemPrivatePtr d;
};
using ItemPtr = std::shared_ptr<Item>;
@@ -181,14 +184,16 @@ public:
bool deleteItem(ItemPtr) noexcept;
+ Collection(KSecretsCollectionPrivatePtr dptr);
protected:
Collection();
Collection(const Collection&) = default;
Collection& operator=(const Collection&) = default;
friend class KSecretsStore;
+ friend class KSecretsStorePrivate;
private:
- std::shared_ptr<CollectionPrivate> d;
+ KSecretsCollectionPrivatePtr d;
};
using CollectionPtr = std::shared_ptr<Collection>;
@@ -221,6 +226,8 @@ public:
CannotOpenFile,
CannotLockFile,
CannotReadFile,
+ PrematureEndOfFileEncountered,
+ UnknownError,
SystemError
};
diff --git a/src/runtime/ksecrets_store/ksecrets_store_p.h \
b/src/runtime/ksecrets_store/ksecrets_store_p.h index c8f8aaa..e3461c1 100644
--- a/src/runtime/ksecrets_store/ksecrets_store_p.h
+++ b/src/runtime/ksecrets_store/ksecrets_store_p.h
@@ -52,6 +52,10 @@ class KSecretsItemPrivate : public TimeStamped {
};
class KSecretsCollectionPrivate : public TimeStamped {
+public:
+ bool createCollection(KSecretsFile &secretsFile, const std::string &collName);
+private:
+ SecretsCollectionPtr collection_data_;
};
class KSecretsStorePrivate {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic