Skip to content

Commit

Permalink
Add sharing of groups between databases
Browse files Browse the repository at this point in the history
* Add source folder keeshare for sharing with corresponding define WITH_XC_KEESHARE
* Move common crypto parts to src/crypto/ssh
* Extended OpenSSHKey
* Move filewatching to own file (currently in two related classes DelayedFileWatcher and BulkFileWatcher)
* Small improvements for style and code in several classes
* Sharing is secured using RSA-Keys which are generated on demand
* Publisher signs the container using their private key
* Client can verify the signed container and choose to decline an import,
import only once or trust the publisher and automatically import all
data of this source henceforth
* Integration of settings into Group-Settings, Database-Settings and Application-Settings
* Introduced dependency QuaZip as dependency to allow combined export of
key container and the (custom format) certificate
  • Loading branch information
Christian Kieschnick authored and droidmonkey committed Oct 1, 2018
1 parent c1e9f45 commit eca9c65
Show file tree
Hide file tree
Showing 106 changed files with 5,807 additions and 482 deletions.
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ option(WITH_XC_NETWORKING "Include networking code (e.g. for downlading website
option(WITH_XC_BROWSER "Include browser integration with keepassxc-browser." OFF)
option(WITH_XC_YUBIKEY "Include YubiKey support." OFF)
option(WITH_XC_SSHAGENT "Include SSH agent support." OFF)
option(WITH_XC_KEESHARE "Include sharing support with KeeShare." OFF)
if(APPLE)
option(WITH_XC_TOUCHID "Include TouchID support for macOS." OFF)
endif()
Expand All @@ -58,11 +59,18 @@ if(WITH_XC_ALL)
set(WITH_XC_BROWSER ON)
set(WITH_XC_YUBIKEY ON)
set(WITH_XC_SSHAGENT ON)
set(WITH_XC_KEESHARE ON)
if(APPLE)
set(WITH_XC_TOUCHID ON)
endif()
endif()

if(WITH_XC_SSHAGENT OR WITH_XC_KEESHARE)
set(WITH_XC_CRYPTO_SSH ON)
else()
set(WITH_XC_CRYPTO_SSH OFF)
endif()

set(KEEPASSXC_VERSION_MAJOR "2")
set(KEEPASSXC_VERSION_MINOR "4")
set(KEEPASSXC_VERSION_PATCH "0")
Expand Down Expand Up @@ -347,6 +355,13 @@ endif()

include_directories(SYSTEM ${ARGON2_INCLUDE_DIR})

# Optional
if(WITH_XC_KEESHARE)
find_package(QuaZip REQUIRED)

include_directories(SYSTEM ${QUAZIP_INCLUDE_DIR})
endif()

# Optional
if(WITH_XC_YUBIKEY)
find_package(YubiKey REQUIRED)
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ RUN set -x \
zlib1g-dev \
libxi-dev \
libxtst-dev \
libquazip5-headers \
libquazip5-dev \
mesa-common-dev \
libyubikey-dev \
libykpers-1-dev
Expand Down
5 changes: 3 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ These steps place the compiled KeePassXC binary inside the `./build/src/` direct
-DWITH_XC_YUBIKEY=[ON|OFF] Enable/Disable YubiKey HMAC-SHA1 authentication support (default: OFF)
-DWITH_XC_BROWSER=[ON|OFF] Enable/Disable KeePassXC-Browser extension support (default: OFF)
-DWITH_XC_NETWORKING=[ON|OFF] Enable/Disable Networking support (favicon download) (default: OFF)
-DWITH_XC_SSHAGENT=[ON|OFF] Include SSH agent support. (default: OFF)
-DWITH_XC_SSHAGENT=[ON|OFF] Enable/Disable SSHAgent support (default: OFF)
-DWITH_XC_SHARING=[ON|OFF] Enable/Disable Sharing extension (default: OFF)
-DWITH_XC_TOUCHID=[ON|OFF] (macOS Only) Enable/Disable Touch ID unlock (default:OFF)
-DWITH_XC_ALL=[ON|OFF] Enable/Disable compiling all plugins above (default: OFF)
-DWITH_TESTS=[ON|OFF] Enable/Disable building of unit tests (default: ON)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ so please check out your distribution's package list to see if KeePassXC is avai
[Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepasshttp-connector/dafgdjggglmmknipkhngniifhplpcldb), and
[passafari](https://github.com/mmichaa/passafari.safariextension/) in Safari. [[See note about KeePassHTTP]](#note-about-keepasshttp)
- Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk)
- Sharing of passwords using KeeShare. See [Using Sharing](./docs/QUICKSTART.md#using-sharing) for more details.
- Many bug fixes

For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
Expand Down
2 changes: 2 additions & 0 deletions ci/trusty/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ RUN set -x \
zlib1g-dev \
libyubikey-dev \
libykpers-1-dev \
libquazip5-headers \
libquazip5-dev \
libxi-dev \
libxtst-dev \
xvfb
Expand Down
6 changes: 3 additions & 3 deletions cmake/CLangFormat.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ set(EXCLUDED_FILES
gui/KMessageWidget.cpp
gui/MainWindowAdaptor.h
gui/MainWindowAdaptor.cpp
sshagent/bcrypt_pbkdf.cpp
sshagent/blf.h
sshagent/blowfish.c
crypto/ssh/bcrypt_pbkdf.cpp
crypto/ssh/blf.h
crypto/ssh/blowfish.c
tests/modeltest.cpp
tests/modeltest.h
# objective-c files
Expand Down
23 changes: 23 additions & 0 deletions cmake/FindQuaZip.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (C) 2018 KeePassXC Team <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 or (at your option)
# version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

find_path(QUAZIP_INCLUDE_DIR quazip5/quazip.h)
find_library(QUAZIP_LIBRARIES quazip5)

mark_as_advanced(QUAZIP_LIBRARIES QUAZIP_INCLUDE_DIR)

include(FindPackageHandleStandardArgs)
include_directories(${QUAZIP_INCLUDE_DIR})
find_package_handle_standard_args(QuaZip DEFAULT_MSG QUAZIP_LIBRARIES QUAZIP_INCLUDE_DIR)
62 changes: 59 additions & 3 deletions docs/QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ Leave the other options at their defaults.
* *In your default web browser,* install the KeePassXC Browser extension/add-on. Instructions for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) or [Chrome](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk)
* Click the KeePassXC icon in the upper-right corner. You'll see the dialog below.
* Click the blue Connect button to make the browser extension connect to the KeePassXC application.
<img src="./KeePassXC-Connect.png" height="200" alt="KeePassXC Connect dialog">
<img src="./KeePassHTTP/KeePassXC-Connect.png" height="200" alt="KeePassXC Connect dialog">

* *Switch back to KeePassXC.* You'll see a dialog (below) indicating that a request to connect has arrived.
* Give the connection a name (perhaps *Keepass-Browsername*, any unique name will suffice) and click OK to accept it.
* This one-time operation connects KeePassXC and your browser.
<img src="./KeePassXC-Accept-Button.png" height="200" alt="KeePassXC accept connection dialog">
<img src="./KeePassHTTP/KeePassXC-Accept-Button.png" height="200" alt="KeePassXC accept connection dialog">

## Using Browser Integration

Expand All @@ -45,4 +45,60 @@ or select it and type Ctrl+U (Cmd+U on macOS).
* If there are username/password fields on that page, you will see the dialog below.
Click *Allow* to confirm that KeePassXC may access the credentials to auto-fill the fields.
* Check *Remember this decision* to allow this each time you visit the page.
<img src="./KeePassXC-Confirm.png" height="200" alt="KeePassCX Confirm Access dialog">
<img src="./KeePassHTTP/KeePassXC-Confirm.png" height="200" alt="KeePassCX Confirm Access dialog">

## Using Sharing

Sharing allows you to share a subset of your credentials with others and vice versa.

### Enable Sharing

To use sharing, you need to enable it on a database.

1. Go to Database &rarr; Database Settings
1. Check _Allow import_ if you want to import shared credentials
1. Check _Allow export_ if you want to share credentials

<img src="./KeeShare/Database-Settings.png" height="600" width="800" alt="KeePassXC Databse Sharing Settings">

### Sharing Credentials

If you checked _Allow export_ in the Sharing settings you now are good to go to share some passwords with others. Sharing always is defined on a group. If you enable sharing on a group, every entry under this group or it's children is shared. If you enable sharing on the root node, **every password** inside your database gets shared!

1. Open the edit sheet on a group you want to share
1. Select the sharing section
1. Choose _Export to path_ as the sharing method
1. Choose a path to store the shared credentials to
1. Generate a password for this share database

The export file will not be generated automatically. Instead, each time the database is saved, the file gets written. If an old file is present, the old file will be overwritten! The file should be written to a location that is accessible by others. An easy setup is a network share or storing the file inside the cloud.

<img src="./KeeShare/Share-Group.png" height="600" width="800" alt="KeePassXC Group Sharing Settings">

### Using Shared Credentials

Checking _Allow import_ in the Sharing settings of the database enables you to receive credentials from others. KeePass will watch sharing sources and import any changes immoderately into your database using the synchronization feature.

1. Create a group for import
1. Open the edit sheet on that group
1. Select the sharing section
1. Choose _Import from path_ as the sharing method
1. Choose a database that is shared with you
1. Enter the password for the shared database

<img src="./KeeShare/Import-Group.png" height="600" width="800" alt="KeePassXC Group Import Settings">

### Using Synchronized Credentials

Instead of using different groups for sharing and importing you can use a single group that acts as both. This way you can synchronize a number of credentials easily across many users without a lot of hassle.

1. Open the edit sheet on a group you want to synchronize
1. Select the sharing section
1. Choose _Synchronize with path_ as the sharing method
1. Choose a database that you want to use a synchronization file
1. Enter the password for the database

<img src="./KeeShare/Synchronize-Group.png" height="600" width="800" alt="KeePassXC Group Synchronization Settings">

## Technical Details of Sharing
Sharing relies on the combination of file exports and imports as well as the synchronization mechanism provided by KeePassXC
23 changes: 21 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ set(keepassx_SOURCES
core/EntryAttributes.cpp
core/EntrySearcher.cpp
core/FilePath.cpp
core/FileWatcher.cpp
core/Global.h
core/Group.cpp
core/InactivityTimer.cpp
Expand Down Expand Up @@ -211,6 +212,7 @@ add_feature_info(Auto-Type WITH_XC_AUTOTYPE "Automatic password typing")
add_feature_info(Networking WITH_XC_NETWORKING "Compile KeePassXC with network access code (e.g. for downloading website icons)")
add_feature_info(KeePassXC-Browser WITH_XC_BROWSER "Browser integration with KeePassXC-Browser")
add_feature_info(SSHAgent WITH_XC_SSHAGENT "SSH agent integration compatible with KeeAgent")
add_feature_info(KeeShare WITH_XC_KEESHARE "Sharing integration with KeeShare")
add_feature_info(YubiKey WITH_XC_YUBIKEY "YubiKey HMAC-SHA1 challenge-response")
if(APPLE)
add_feature_info(TouchID WITH_XC_TOUCHID "TouchID integration")
Expand All @@ -226,6 +228,17 @@ endif()
add_subdirectory(autotype)
add_subdirectory(cli)

add_subdirectory(crypto/ssh)
if(WITH_XC_CRYPTO_SSH)
set(crypto_ssh_LIB crypto_ssh)
endif()


add_subdirectory(keeshare)
if(WITH_XC_KEESHARE)
set(keeshare_LIB keeshare)
endif()

add_subdirectory(sshagent)
if(WITH_XC_SSHAGENT)
set(sshagent_LIB sshagent)
Expand Down Expand Up @@ -269,7 +282,6 @@ set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUIL
target_link_libraries(keepassx_core
autotype
${keepassxcbrowser_LIB}
${sshagent_LIB}
Qt5::Core
Qt5::Network
Qt5::Concurrent
Expand All @@ -280,7 +292,14 @@ target_link_libraries(keepassx_core
${ARGON2_LIBRARIES}
${GCRYPT_LIBRARIES}
${GPGERROR_LIBRARIES}
${ZLIB_LIBRARIES})
${ZLIB_LIBRARIES})

if(WITH_XC_SSHAGENT)
target_link_libraries(keepassx_core sshagent)
endif()
if(WITH_XC_KEESHARE)
target_link_libraries(keepassx_core keeshare)
endif()

if(APPLE)
target_link_libraries(keepassx_core "-framework Foundation")
Expand Down
1 change: 1 addition & 0 deletions src/config-keepassx.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#cmakedefine WITH_XC_BROWSER
#cmakedefine WITH_XC_YUBIKEY
#cmakedefine WITH_XC_SSHAGENT
#cmakedefine WITH_XC_KEESHARE
#cmakedefine WITH_XC_TOUCHID

#cmakedefine KEEPASSXC_BUILD_TYPE "@KEEPASSXC_BUILD_TYPE@"
Expand Down
4 changes: 2 additions & 2 deletions src/core/Clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/
#include "Clock.h"

QSharedPointer<Clock> Clock::m_instance = QSharedPointer<Clock>();
QSharedPointer<Clock> Clock::m_instance;

QDateTime Clock::currentDateTimeUtc()
{
Expand Down Expand Up @@ -92,7 +92,7 @@ QDateTime Clock::currentDateTimeImpl() const

void Clock::resetInstance()
{
m_instance.clear();
m_instance.reset();
}

void Clock::setInstance(Clock* clock)
Expand Down
9 changes: 9 additions & 0 deletions src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ QString Config::getFileName()

void Config::set(const QString& key, const QVariant& value)
{
if (m_settings->contains(key) && m_settings->value(key) == value) {
return;
}
const bool surpressSignal = !m_settings->contains(key) && m_defaults.value(key) == value;

m_settings->setValue(key, value);

if (!surpressSignal) {
emit changed(key);
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Config : public QObject
static void createConfigFromFile(const QString& file);
static void createTempFileInstance();

signals:
void changed(const QString& key);

private:
Config(const QString& fileName, QObject* parent);
explicit Config(QObject* parent);
Expand Down
11 changes: 7 additions & 4 deletions src/core/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void Database::setFilePath(const QString& filePath)
m_filePath = filePath;
}

Entry* Database::resolveEntry(const QUuid& uuid)
Entry* Database::resolveEntry(const QUuid& uuid) const
{
return findEntryRecursive(uuid, m_rootGroup);
}
Expand All @@ -121,7 +121,7 @@ Entry* Database::resolveEntry(const QString& text, EntryReferenceType referenceT
return findEntryRecursive(text, referenceType, m_rootGroup);
}

Entry* Database::findEntryRecursive(const QUuid& uuid, Group* group)
Entry* Database::findEntryRecursive(const QUuid& uuid, Group* group) const
{
const QList<Entry*> entryList = group->entries();
for (Entry* entry : entryList) {
Expand Down Expand Up @@ -289,8 +289,11 @@ QByteArray Database::challengeResponseKey() const

bool Database::challengeMasterSeed(const QByteArray& masterSeed)
{
m_data.masterSeed = masterSeed;
return m_data.key->challenge(masterSeed, m_data.challengeResponseKey);
if (m_data.key) {
m_data.masterSeed = masterSeed;
return m_data.key->challenge(masterSeed, m_data.challengeResponseKey);
}
return true;
}

void Database::setCipher(const QUuid& cipher)
Expand Down
5 changes: 3 additions & 2 deletions src/core/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <QHash>
#include <QObject>

#include "config-keepassx.h"
#include "crypto/kdf/Kdf.h"
#include "keys/CompositeKey.h"

Expand Down Expand Up @@ -88,7 +89,7 @@ class Database : public QObject
const Metadata* metadata() const;
QString filePath() const;
void setFilePath(const QString& filePath);
Entry* resolveEntry(const QUuid& uuid);
Entry* resolveEntry(const QUuid& uuid) const;
Entry* resolveEntry(const QString& text, EntryReferenceType referenceType);
Group* resolveGroup(const QUuid& uuid);
QList<DeletedObject> deletedObjects();
Expand Down Expand Up @@ -149,7 +150,7 @@ private slots:
void startModifiedTimer();

private:
Entry* findEntryRecursive(const QUuid& uuid, Group* group);
Entry* findEntryRecursive(const QUuid& uuid, Group* group) const;
Entry* findEntryRecursive(const QString& text, EntryReferenceType referenceType, Group* group);
Group* findGroupRecursive(const QUuid& uuid, Group* group);

Expand Down
2 changes: 2 additions & 0 deletions src/core/DatabaseIcons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
DatabaseIcons* DatabaseIcons::m_instance(nullptr);
const int DatabaseIcons::IconCount(69);
const int DatabaseIcons::ExpiredIconIndex(45);
const int DatabaseIcons::SharedIconIndex(1);
const int DatabaseIcons::UnsharedIconIndex(45);

// clang-format off
const char* const DatabaseIcons::m_indexToName[] = {
Expand Down
2 changes: 2 additions & 0 deletions src/core/DatabaseIcons.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class DatabaseIcons

static const int IconCount;
static const int ExpiredIconIndex;
static const int SharedIconIndex;
static const int UnsharedIconIndex;

private:
DatabaseIcons();
Expand Down
Loading

0 comments on commit eca9c65

Please sign in to comment.