aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/odhtdb/Database.hpp2
-rw-r--r--include/odhtdb/DatabaseStorage.hpp47
-rw-r--r--include/odhtdb/Group.hpp1
-rw-r--r--include/odhtdb/LocalUser.hpp5
-rw-r--r--include/odhtdb/User.hpp2
-rw-r--r--src/Database.cpp7
-rw-r--r--src/DatabaseStorage.cpp68
-rw-r--r--src/Group.cpp13
-rw-r--r--src/User.cpp8
9 files changed, 139 insertions, 14 deletions
diff --git a/include/odhtdb/Database.hpp b/include/odhtdb/Database.hpp
index 3e4a393..9aff90e 100644
--- a/include/odhtdb/Database.hpp
+++ b/include/odhtdb/Database.hpp
@@ -140,6 +140,8 @@ namespace odhtdb
void seed(const DatabaseNode &nodeToSeed);
// Throws DatabaseCreateException on failure.
std::unique_ptr<DatabaseCreateResponse> create(const std::string &ownerName, const std::string &nodeName);
+ // Throws DatabaseCreateException on failure.
+ std::unique_ptr<DatabaseCreateResponse> create(const std::string &ownerName, const Signature::KeyPair &keyPair, const std::string &nodeName);
// Throws DatabaseAddException on failure
void addData(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, DataView dataToAdd);
// Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo
diff --git a/include/odhtdb/DatabaseStorage.hpp b/include/odhtdb/DatabaseStorage.hpp
index f3c3087..34e523e 100644
--- a/include/odhtdb/DatabaseStorage.hpp
+++ b/include/odhtdb/DatabaseStorage.hpp
@@ -43,22 +43,41 @@ namespace odhtdb
DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey);
};
- class DatabaseStorageAlreadyExists : public std::runtime_error
+ class DatabaseStorageException : public std::runtime_error
{
public:
- DatabaseStorageAlreadyExists(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ DatabaseStorageException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ virtual ~DatabaseStorageException() {}
};
- class DatabaseStorageNotFound : public std::runtime_error
+ class DatabaseStorageAlreadyExists : public DatabaseStorageException
{
public:
- DatabaseStorageNotFound(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ DatabaseStorageAlreadyExists(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
};
- class DatabaseStorageCorrupt : public std::runtime_error
+ class DatabaseStorageNotFound : public DatabaseStorageException
{
public:
- DatabaseStorageCorrupt(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ DatabaseStorageNotFound(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
+ };
+
+ class DatabaseStorageCorrupt : public DatabaseStorageException
+ {
+ public:
+ DatabaseStorageCorrupt(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
+ };
+
+ class DatabaseStorageNoSuchLocalStorageUser : public DatabaseStorageException
+ {
+ public:
+ DatabaseStorageNoSuchLocalStorageUser(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
+ };
+
+ class DatabaseStorageWrongPassword : public DatabaseStorageException
+ {
+ public:
+ DatabaseStorageWrongPassword(const std::string &errMsg) : DatabaseStorageException(errMsg) {}
};
using DatabaseStorageMap = MapHash<DatabaseStorageObjectList*>;
@@ -67,6 +86,8 @@ namespace odhtdb
const int PASSWORD_SALT_LEN = 16;
const int HASHED_PASSWORD_LEN = 32;
+ using NodeLocalUser = std::pair<Hash, LocalUser*>;
+
class DatabaseStorage
{
public:
@@ -98,8 +119,18 @@ namespace odhtdb
// Returns nullptr if a user with public key @publicKey doesn't exist in node @nodeHash or if no node with id @nodeHash exists
User* getUserByPublicKey(const Hash &nodeHash, const Signature::PublicKey &userPublicKey) const;
- // Username, public key and private key has to be unique
- bool storeLocalUser(const std::string &username, const Signature::PublicKey &publicKey, const Signature::PrivateKey &privateKey, const std::string &password);
+ // Username and key pair has to be unique, returns true on success
+ bool storeLocalUser(const std::string &username, const Signature::KeyPair &keyPair, const std::string &password);
+
+ // Returns public key and private key of encrypted local user.
+ // Throws DatabaseStorageNoSuchLocalStorageUser if user does not exist in local storage.
+ // Throws DatabaseStorageWrongPassword if password for the stored local user is wrong.
+ Signature::KeyPair decryptLocalEncryptedUser(const std::string &username, const std::string &password);
+
+ // Get stored local user by public & private key in all nodes they exist.
+ // Creates a new user object and replaces user object in the nodes.
+ // Safe to call multiple times.
+ std::vector<NodeLocalUser> getLocalNodeUsers(const Signature::KeyPair &keyPair);
const dht::crypto::Identity& getIdentity() const;
diff --git a/include/odhtdb/Group.hpp b/include/odhtdb/Group.hpp
index 890b2fc..cd28923 100644
--- a/include/odhtdb/Group.hpp
+++ b/include/odhtdb/Group.hpp
@@ -36,6 +36,7 @@ namespace odhtdb
const std::vector<const User*>& getUsers() const;
private:
void addUser(const User *user);
+ bool removeUser(const User *user);
private:
std::string name;
uint8_t id[GROUP_ID_LENGTH];
diff --git a/include/odhtdb/LocalUser.hpp b/include/odhtdb/LocalUser.hpp
index b9bdde6..c87ba45 100644
--- a/include/odhtdb/LocalUser.hpp
+++ b/include/odhtdb/LocalUser.hpp
@@ -22,6 +22,11 @@ namespace odhtdb
{
return keyPair.getPrivateKey();
}
+
+ const Signature::KeyPair& getKeyPair() const
+ {
+ return keyPair;
+ }
private:
LocalUser(const Signature::KeyPair &_keyPair, const std::string &name, Group *group);
private:
diff --git a/include/odhtdb/User.hpp b/include/odhtdb/User.hpp
index 3236d4c..beb8974 100644
--- a/include/odhtdb/User.hpp
+++ b/include/odhtdb/User.hpp
@@ -29,7 +29,7 @@ namespace odhtdb
REMOTE
};
- virtual ~User(){}
+ virtual ~User();
virtual void addToGroup(Group *group);
diff --git a/src/Database.cpp b/src/Database.cpp
index 9b01f72..bdf9104 100644
--- a/src/Database.cpp
+++ b/src/Database.cpp
@@ -234,11 +234,16 @@ namespace odhtdb
unique_ptr<DatabaseCreateResponse> Database::create(const string &ownerName, const string &nodeName)
{
+ return create(ownerName, Signature::KeyPair(), nodeName);
+ }
+
+ unique_ptr<DatabaseCreateResponse> Database::create(const string &ownerName, const Signature::KeyPair &keyPair, const string &nodeName)
+ {
// TODO: Should this be declared static? is there any difference in behavior/performance?
boost::uuids::random_generator uuidGen;
auto adminGroupId = uuidGen();
auto adminGroup = new Group("administrator", adminGroupId.data, ADMIN_PERMISSION);
- LocalUser *nodeAdminUser = LocalUser::create(Signature::KeyPair(), ownerName, adminGroup);
+ LocalUser *nodeAdminUser = LocalUser::create(keyPair, ownerName, adminGroup);
// Header
sibs::SafeSerializer serializer;
diff --git a/src/DatabaseStorage.cpp b/src/DatabaseStorage.cpp
index 7ce4919..34e6da4 100644
--- a/src/DatabaseStorage.cpp
+++ b/src/DatabaseStorage.cpp
@@ -533,14 +533,14 @@ namespace odhtdb
return nullptr;
}
- bool DatabaseStorage::storeLocalUser(const string &username, const Signature::PublicKey &publicKey, const Signature::PrivateKey &privateKey, const string &password)
+ bool DatabaseStorage::storeLocalUser(const string &username, const Signature::KeyPair &keyPair, const string &password)
{
auto it = nameLocalUsersMap.find(username);
if(it != nameLocalUsersMap.end())
return false;
OwnedMemory hashedPassword = hashPassword(DataView((void*)password.data(), password.size()), DataView((void*)passwordSalt, PASSWORD_SALT_LEN));
- DataView privateKeyView((void*)privateKey.getData(), PRIVATE_KEY_NUM_BYTES);
+ DataView privateKeyView((void*)keyPair.getPrivateKey().getData(), PRIVATE_KEY_NUM_BYTES);
DataView hashedPasswordView(hashedPassword.data, hashedPassword.size);
Encryption encryptedPrivateKey(privateKeyView, {}, hashedPasswordView);
@@ -549,13 +549,13 @@ namespace odhtdb
assert(sizeof(userEncryptedPrivateKey.encryptedPrivateKey) == encryptedPrivateKey.getCipherText().size);
memcpy(userEncryptedPrivateKey.encryptedPrivateKey, encryptedPrivateKey.getCipherText().data, encryptedPrivateKey.getCipherText().size);
- LocalUserEncrypted *localUserEncrypted = LocalUserEncrypted::create(publicKey, userEncryptedPrivateKey, username);
+ LocalUserEncrypted *localUserEncrypted = LocalUserEncrypted::create(keyPair.getPublicKey(), userEncryptedPrivateKey, username);
nameLocalUsersMap[username] = localUserEncrypted;
sibs::SafeSerializer serializer;
serializer.add((u8)username.size());
serializer.add((const u8*)username.data(), username.size());
- serializer.add((const u8*)publicKey.getData(), PUBLIC_KEY_NUM_BYTES);
+ serializer.add((const u8*)keyPair.getPublicKey().getData(), PUBLIC_KEY_NUM_BYTES);
serializer.add((const u8*)encryptedPrivateKey.getNonce().data, ENCRYPTION_NONCE_BYTE_SIZE);
serializer.add((const u8*)encryptedPrivateKey.getCipherText().data, ENCRYPTION_CHECKSUM_BYTE_SIZE + PRIVATE_KEY_NUM_BYTES);
@@ -563,6 +563,66 @@ namespace odhtdb
return true;
}
+ Signature::KeyPair DatabaseStorage::decryptLocalEncryptedUser(const string &username, const string &password)
+ {
+ auto localUserIt = nameLocalUsersMap.find(username);
+ if(localUserIt == nameLocalUsersMap.end())
+ {
+ string errMsg = "User ";
+ errMsg += username;
+ errMsg += " does not exist in local storage";
+ throw DatabaseStorageNoSuchLocalStorageUser(errMsg);
+ }
+
+ DataView passwordView((void*)password.data(), password.size());
+ DataView saltView((void*)passwordSalt, PASSWORD_SALT_LEN);
+ try
+ {
+ auto privateKey = localUserIt->second->getPrivateKey().decrypt(passwordView, saltView);
+ Signature::KeyPair keyPair(localUserIt->second->getPublicKey(), privateKey);
+ return keyPair;
+ }
+ catch(DecryptionException &e)
+ {
+ string errMsg = "Wrong password provided for user ";
+ errMsg += username;
+ errMsg += " in local storage (";
+ errMsg += e.what();
+ errMsg += ")";
+ throw DatabaseStorageWrongPassword(errMsg);
+ }
+ }
+
+ vector<NodeLocalUser> DatabaseStorage::getLocalNodeUsers(const Signature::KeyPair &keyPair)
+ {
+ vector<NodeLocalUser> localUsers;
+
+ for(auto nodeIt : nodePublicKeyUserDataMap)
+ {
+ auto userIt = nodeIt.second->find(keyPair.getPublicKey());
+ if(userIt != nodeIt.second->end())
+ {
+ User *user = userIt->second;
+ if(user->getType() != User::Type::LOCAL)
+ {
+ LocalUser *localUser = LocalUser::create(keyPair, user->getName(), nullptr);
+ for(Group *group : user->getGroups())
+ {
+ localUser->addToGroup(group);
+ }
+
+ (*nodeIt.second)[keyPair.getPublicKey()] = localUser;
+ localUsers.push_back(make_pair(nodeIt.first, localUser));
+ delete user;
+ }
+ else
+ localUsers.push_back(make_pair(nodeIt.first, static_cast<LocalUser*>(user)));
+ }
+ }
+
+ return localUsers;
+ }
+
const dht::crypto::Identity& DatabaseStorage::getIdentity() const
{
return identity;
diff --git a/src/Group.cpp b/src/Group.cpp
index a99fdf6..4210142 100644
--- a/src/Group.cpp
+++ b/src/Group.cpp
@@ -24,6 +24,19 @@ namespace odhtdb
{
users.push_back(user);
}
+
+ bool Group::removeUser(const User *user)
+ {
+ for(std::vector<const User*>::iterator it = users.begin(); it != users.end(); ++it)
+ {
+ if(*it == user)
+ {
+ users.erase(it);
+ return true;
+ }
+ }
+ return false;
+ }
const string& Group::getName() const
{
diff --git a/src/User.cpp b/src/User.cpp
index 1fb4a11..d157c74 100644
--- a/src/User.cpp
+++ b/src/User.cpp
@@ -10,6 +10,14 @@ namespace odhtdb
addToGroup(group);
}
+ User::~User()
+ {
+ for(Group *group : groups)
+ {
+ group->removeUser(this);
+ }
+ }
+
void User::addToGroup(Group *group)
{
if(group)