>();
59 | }
60 |
--------------------------------------------------------------------------------
/webapp/AboutDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.11
2 | import QtQuick.Controls 2.4
3 | import de.skycoder42.kpt 1.0
4 |
5 | Dialog {
6 | id: errorDialog
7 | x: (appWindow.width - errorDialog.width) / 2
8 | y: (appWindow.height - errorDialog.height) / 2
9 | title: qsTr("About %1 — Version %2").arg(Qt.application.displayName).arg(Qt.application.version)
10 | standardButtons: Dialog.Ok
11 | modal: true
12 |
13 | Label {
14 | id: textLabel
15 | anchors.fill: parent
16 | text: qsTr("A tool to securely transfer passwords and other credentials from any device to a remote computer for easy access anywhere.
17 | Qt-Version: %1
18 | Developed by: Skycoder42
19 | Project Website: https://github.com/Skycoder42/KeepassTransfer
20 | License: GPL-3.0
21 | Attributions:
").arg(qtVersion)
33 |
34 | onLinkActivated: emjscon.openUrl(link)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/clients/quick/KptRootDrawer.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.11
2 | import QtQuick.Controls 2.4
3 | import QtQuick.Controls.Material 2.4
4 | import QtQuick.Layouts 1.3
5 | import de.skycoder42.QtMvvm.Core 1.1
6 | import de.skycoder42.QtMvvm.Quick 1.1
7 | import de.skycoder42.kpt 1.0
8 |
9 | ColumnLayout {
10 | id: rootDrawer
11 | property KptRootViewModel viewModel: null
12 | property Drawer drawer: null
13 |
14 | anchors.fill: parent
15 | spacing: 0
16 |
17 | ColorHelper {
18 | id: helper
19 | }
20 |
21 | Rectangle {
22 | id: headerRect
23 | Layout.fillWidth: true
24 | Layout.preferredHeight: width * 0.666
25 | color: QuickPresenter.currentStyle == "Material" ? Material.primary : helper.highlight
26 |
27 | ColumnLayout {
28 | anchors.fill: parent
29 |
30 | TintIcon {
31 | Layout.alignment: Qt.AlignCenter
32 | icon.source: "qrc:/icons/main.svg"
33 | icon.color: Material.accent
34 | icon.width: parent.height * 0.666
35 | icon.height: parent.height * 0.666
36 | }
37 |
38 | ToolBarLabel {
39 | Layout.fillWidth: true
40 | Layout.bottomMargin: 8
41 | text: Qt.application.displayName
42 | }
43 | }
44 | }
45 |
46 | ItemDelegate {
47 | Layout.fillWidth: true
48 | display: Button.TextBesideIcon
49 | icon.name: "settings-configure"
50 | icon.source: "qrc:/de/skycoder42/qtmvvm/icons/settings.svg"
51 | text: qsTr("Settings")
52 | onClicked: {
53 | viewModel.showSettings();
54 | drawer.close();
55 | }
56 | }
57 |
58 | MenuSeparator {
59 | Layout.fillWidth: true
60 | topPadding: 0
61 | bottomPadding: 0
62 | }
63 |
64 | ItemDelegate {
65 | Layout.fillWidth: true
66 | display: Button.TextBesideIcon
67 | icon.name: "help-about"
68 | icon.source: "qrc:/icons/about.svg"
69 | text: qsTr("About this App")
70 | onClicked: viewModel.about()
71 | }
72 |
73 | MenuSeparator {
74 | Layout.fillWidth: true
75 | topPadding: 0
76 | bottomPadding: 0
77 | }
78 |
79 | Item {
80 | id: spacer
81 | Layout.fillHeight: true
82 | Layout.fillWidth: true
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/clients/quick/TransferSelectionView.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.11
2 | import QtQuick.Controls 2.4
3 | import QtQuick.Layouts 1.3
4 | import de.skycoder42.QtMvvm.Core 1.1
5 | import de.skycoder42.QtMvvm.Quick 1.1
6 | import de.skycoder42.kpt 1.0
7 |
8 | Page {
9 | id: mainView
10 | property TransferSelectionViewModel viewModel: null
11 |
12 | header: ContrastToolBar {
13 | RowLayout {
14 | anchors.fill: parent
15 | spacing: 0
16 |
17 | ActionButton {
18 | icon.name: "open-menu-symbolic"
19 | icon.source: "qrc:/icons/menu.svg"
20 | onClicked: QuickPresenter.toggleDrawer()
21 | }
22 |
23 | ToolBarLabel {
24 | text: qsTr("Select a mode")
25 | Layout.fillWidth: true
26 | }
27 | }
28 | }
29 |
30 | PresenterProgress {}
31 |
32 | ScrollView {
33 | id: scrollView
34 | anchors.fill: parent
35 |
36 | ListView {
37 | id: listView
38 |
39 | model: viewModel.modeModel
40 |
41 | delegate: ItemDelegate {
42 | width: scrollView.width
43 |
44 | onClicked: viewModel.startTransfer(index)
45 |
46 | Component.onCompleted: height = Qt.binding(function(){ return grid.implicitHeight + padding; })
47 |
48 | contentItem: GridLayout {
49 | id: grid
50 | rows: 2
51 | columns: 2
52 | columnSpacing: 16
53 |
54 | Label {
55 | id: titleLabel
56 | text: edit
57 | Layout.row: 0
58 | Layout.column: 0
59 | font.bold: true
60 | elide: Label.ElideRight
61 | Layout.fillWidth: true
62 | }
63 |
64 | Label {
65 | id: textLabel
66 | Layout.row: 1
67 | Layout.column: 0
68 | text: toolTip
69 | wrapMode: Text.WordWrap
70 | Layout.fillWidth: true
71 | }
72 |
73 | TintIcon {
74 | id: openIcon
75 | icon.source: "qrc:/de/skycoder42/qtmvvm/quick/icons/ic_chevron_right.svg"
76 | Layout.row: 0
77 | Layout.column: 2
78 | Layout.rowSpan: 2
79 | Layout.fillHeight: true
80 | Layout.preferredWidth: implicitWidth
81 | Layout.preferredHeight: implicitHeight
82 | Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
83 | }
84 | }
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/webapp/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "qrencoder.h"
10 | #include "passencoder.h"
11 | #include "qrimageprovider.h"
12 | #include "emjsconnector.h"
13 |
14 | #ifdef QT_OS_WASM
15 | #include "qwasmsettings.h"
16 | #endif
17 |
18 | int main(int argc, char *argv[])
19 | {
20 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
21 |
22 | QGuiApplication app(argc, argv);
23 | QCoreApplication::setApplicationName(QStringLiteral(PROJECT_TARGET));
24 | QCoreApplication::setApplicationVersion(QStringLiteral(VERSION));
25 | QCoreApplication::setOrganizationName(QStringLiteral(COMPANY));
26 | QCoreApplication::setOrganizationDomain(QStringLiteral(BUNDLE));
27 | QGuiApplication::setApplicationDisplayName(QStringLiteral(PROJECT_NAME));
28 | QGuiApplication::setWindowIcon(QIcon{QStringLiteral(":/icons/main.svg")});
29 |
30 | #ifdef QT_OS_WASM
31 | QWasmSettings::registerFormat();
32 | #endif
33 |
34 | KPTLib::setup();
35 |
36 | qmlRegisterUncreatableType("de.skycoder42.kpt", 1, 0, "Credential", {});
37 | qmlRegisterUncreatableType("de.skycoder42.kpt", 1, 0, "ServerConnector", {});
38 | qmlRegisterUncreatableType("de.skycoder42.kpt", 1, 0, "DataEncryptor", {});
39 | qmlRegisterType("de.skycoder42.kpt", 1, 0, "QrEncoder");
40 | qmlRegisterType("de.skycoder42.kpt", 1, 0, "PassEncoder");
41 |
42 | ServerConnector connector{EmJsConnector::instance()->getHostUrl()};
43 |
44 | QQmlApplicationEngine engine;
45 | engine.addImageProvider(QStringLiteral("qrcode"), new QrImageProvider{});
46 | engine.rootContext()->setContextProperty(QStringLiteral("connector"), &connector);
47 | engine.rootContext()->setContextProperty(QStringLiteral("emjscon"), EmJsConnector::instance());
48 | engine.rootContext()->setContextProperty(QStringLiteral("qtVersion"), QStringLiteral(QT_VERSION_STR));
49 |
50 | engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
51 | if (engine.rootObjects().isEmpty())
52 | return -1;
53 |
54 | return app.exec();
55 | }
56 |
--------------------------------------------------------------------------------
/clients/core/passconnectorviewmodel.h:
--------------------------------------------------------------------------------
1 | #ifndef PASSCONNECTORVIEWMODEL_H
2 | #define PASSCONNECTORVIEWMODEL_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "passclientencryptor.h"
9 |
10 | class PassConnectorViewModel : public QtMvvm::ViewModel
11 | {
12 | Q_OBJECT
13 | QTMVVM_CONTAINER_VM(KptRootViewModel)
14 |
15 | QTMVVM_INJECT_PROP(DataEncryptor*, encryptor, _encryptor)
16 | QTMVVM_INJECT_PROP(Settings*, settings, _settings)
17 | QTMVVM_INJECT_PROP(ClientTransferService*, transferService, _transferService)
18 |
19 | Q_PROPERTY(QRegularExpressionValidator* channelIdValidator READ channelIdValidator CONSTANT)
20 |
21 | Q_PROPERTY(QString channelIdStr READ channelIdStr WRITE setChannelIdStr NOTIFY channelIdChanged)
22 | Q_PROPERTY(QUuid channelId READ channelId WRITE setChannelId NOTIFY channelIdChanged)
23 | Q_PROPERTY(QString passphrase READ passphrase WRITE setPassphrase NOTIFY passphraseChanged)
24 | Q_PROPERTY(bool valid READ isValid NOTIFY channelIdChanged)
25 |
26 | public:
27 | Q_INVOKABLE explicit PassConnectorViewModel(QObject *parent = nullptr);
28 |
29 | QRegularExpressionValidator* channelIdValidator() const;
30 | QUuid channelId() const;
31 | QString channelIdStr() const;
32 | QString passphrase() const;
33 | bool isValid() const;
34 |
35 | public slots:
36 | bool transfer();
37 | void generateRandomPassphrase();
38 |
39 | void onInit(const QVariantHash ¶ms) override;
40 |
41 | void setChannelId(QUuid channelId);
42 | void setChannelIdStr(QString channelIdStr);
43 | void setPassphrase(QString passphrase);
44 |
45 | signals:
46 | void channelIdChanged();
47 | void passphraseChanged(const QString &passphrase);
48 |
49 | private slots:
50 | void transferDone();
51 |
52 | private:
53 | CryptoPP::AutoSeededRandomPool _rng;
54 |
55 | DataEncryptor *_encryptor = nullptr;
56 | Settings *_settings = nullptr;
57 | ClientTransferService *_transferService = nullptr;
58 | PassClientEncryptor *_passCryptor = nullptr;
59 | QRegularExpressionValidator* _channelIdValidator;
60 |
61 | QList _credentials;
62 | };
63 |
64 | #endif // PASSCONNECTORVIEWMODEL_H
65 |
--------------------------------------------------------------------------------
/clients/quick/android/src/de/skycoder42/kpt/TransferActionReceiver.java:
--------------------------------------------------------------------------------
1 | package de.skycoder42.kpt;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 |
6 | import android.os.Bundle;
7 |
8 | import android.util.Log;
9 |
10 | import org.json.JSONArray;
11 | import org.json.JSONException;
12 |
13 | import keepass2android.pluginsdk.PluginActionBroadcastReceiver;
14 | import keepass2android.pluginsdk.PluginAccessException;
15 | import keepass2android.pluginsdk.Strings;
16 |
17 | public class TransferActionReceiver extends PluginActionBroadcastReceiver {
18 | private Intent _currentIntent;
19 |
20 | @Override
21 | protected void openEntry(OpenEntryAction oe) {
22 | try {
23 | oe.addEntryAction(oe.getContext().getString(R.string.action_entry),
24 | R.mipmap.ic_foreground,
25 | new Bundle());
26 | } catch (PluginAccessException e) {
27 | Log.getStackTraceString(e);
28 | }
29 | }
30 |
31 | @Override
32 | protected void actionSelected(ActionSelectedAction actionSelected) {
33 | Intent intent = new Intent(actionSelected.getContext(), KptActivity.class);
34 |
35 | intent.putExtra(KptActivity.DataEntriesExtra, actionSelected.getEntryFields());
36 |
37 | String[] protFields = actionSelected.getProtectedFieldsList();
38 | if (protFields == null) {//in case it was fixed -> only if not successful (see https://github.com/PhilippC/keepass2android/issues/627)
39 | try {
40 | JSONArray fieldData = new JSONArray(_currentIntent.getStringExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST));
41 | protFields = new String[fieldData.length()];
42 | for(int i = 0; i < fieldData.length(); i++)
43 | protFields[i] = fieldData.getString(i);
44 | } catch(JSONException e) {
45 | Log.getStackTraceString(e);
46 | protFields = new String[0];
47 | }
48 | }
49 | intent.putExtra(KptActivity.GuardedEntriesExtra, protFields);
50 |
51 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
52 | actionSelected.getContext().startActivity(intent);
53 | }
54 |
55 | @Override
56 | public void onReceive(Context context, Intent intent) {
57 | _currentIntent = intent;
58 | super.onReceive(context, intent);
59 | _currentIntent = null;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/webapp/PassTabView.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.11
2 | import QtQuick.Controls 2.4
3 | import QtQuick.Controls.Material 2.4
4 | import QtQuick.Layouts 1.3
5 | import Qt.labs.settings 1.0
6 | import de.skycoder42.kpt 1.0
7 |
8 | Pane {
9 | id: passView
10 |
11 | PassEncoder {
12 | id: encoder
13 | }
14 |
15 | ColumnLayout {
16 | id: contentLayout
17 | anchors.fill: parent
18 |
19 | GroupBox {
20 | id: passGroup
21 | title: qsTr("Passphrase and Identity")
22 | Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
23 | Layout.preferredWidth: 500
24 | Layout.minimumWidth: 0
25 |
26 | GridLayout {
27 | anchors.fill: parent
28 | columns: 4
29 | columnSpacing: 16
30 |
31 | Label {
32 | text: qsTr("Identity:")
33 | Layout.alignment: Qt.AlignLeft
34 | }
35 |
36 | TextField {
37 | id: idField
38 | Layout.fillWidth: true
39 | Layout.columnSpan: 3
40 | readOnly: true
41 | selectByMouse: true
42 | text: connector.appIdStr
43 | }
44 |
45 | Label {
46 | text: qsTr("Passphrase:")
47 | Layout.alignment: Qt.AlignLeft
48 | }
49 |
50 | TextField {
51 | id: passField
52 | Layout.fillWidth: true
53 | selectByMouse: true
54 | echoMode: visButton.checked ? TextField.Normal : TextField.Password
55 |
56 | text: encoder.passphrase
57 | onTextEdited: encoder.passphrase = text
58 | }
59 |
60 | ToolButton {
61 | id: visButton
62 | flat: true
63 | checkable: true
64 | icon.name: checked ? "show_table_column" : "hide_table_column"
65 | icon.source: checked ? "qrc:/icons/show.svg" : "qrc:/icons/hide.svg"
66 | checked: false
67 |
68 | ToolTip.visible: pressed
69 | ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
70 | ToolTip.text: qsTr("Toggle the visibility of the password")
71 | }
72 |
73 | ToolButton {
74 | id: generateButton
75 | flat: true
76 | icon.name: "password-generate"
77 | icon.source: "qrc:/icons/key.svg"
78 | onClicked: encoder.generateRandom()
79 |
80 | ToolTip.visible: pressed
81 | ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
82 | ToolTip.text: qsTr("Generate a new, 16 character password")
83 | }
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/install.pri:
--------------------------------------------------------------------------------
1 | # installing
2 | isEmpty(PREFIX) {
3 | PREFIX = $$[QT_INSTALL_PREFIX]
4 | isEmpty(INSTALL_BINS): INSTALL_BINS = $$[QT_INSTALL_BINS]
5 | isEmpty(INSTALL_APPS): INSTALL_APPS = $$INSTALL_BINS
6 | isEmpty(INSTALL_LIBS): INSTALL_LIBS = $$[QT_INSTALL_LIBS]
7 | isEmpty(INSTALL_HEADERS): INSTALL_HEADERS = $$[QT_INSTALL_HEADERS]
8 | isEmpty(INSTALL_PLUGINS): INSTALL_PLUGINS = $$[QT_INSTALL_PLUGINS]
9 | isEmpty(INSTALL_TRANSLATIONS): INSTALL_TRANSLATIONS = $$[QT_INSTALL_TRANSLATIONS]
10 | isEmpty(INSTALL_SHARE): INSTALL_SHARE = $${PREFIX}/share
11 | CONFIG += no_deploy_qt_qm
12 | } else:!no_bundle_deploy:mac {
13 | APP_PREFIX = $${PROJECT_NAME}.app/Contents
14 | isEmpty(INSTALL_APPS): INSTALL_APPS = $${PREFIX}/.app-tmp
15 | isEmpty(INSTALL_BINS): INSTALL_BINS = $${PREFIX}/$${APP_PREFIX}/MacOS
16 | isEmpty(INSTALL_LIBS): INSTALL_LIBS = $${PREFIX}/$${APP_PREFIX}/Frameworks
17 | isEmpty(INSTALL_HEADERS): INSTALL_HEADERS = $${PREFIX}/$${APP_PREFIX}/Headers
18 | isEmpty(INSTALL_PLUGINS): INSTALL_PLUGINS = $${PREFIX}/$${APP_PREFIX}/PlugIns
19 | isEmpty(INSTALL_TRANSLATIONS): INSTALL_TRANSLATIONS = $${PREFIX}/$${APP_PREFIX}/Resources/translations
20 | isEmpty(INSTALL_SHARE): INSTALL_SHARE = $${PREFIX}/$${APP_PREFIX}/Resources
21 | } else {
22 | # bins
23 | !no_bundle_deploy:win32:isEmpty(INSTALL_BINS): INSTALL_BINS = $$PREFIX
24 | isEmpty(INSTALL_BINS): INSTALL_BINS = $${PREFIX}/bin
25 | isEmpty(INSTALL_APPS): INSTALL_APPS = $$INSTALL_BINS
26 |
27 | # libs
28 | !no_bundle_deploy:win32:isEmpty(INSTALL_LIBS): INSTALL_LIBS = $$INSTALL_BINS
29 | else:isEmpty(INSTALL_LIBS): INSTALL_LIBS = $${PREFIX}/lib
30 |
31 | # headers
32 | isEmpty(INSTALL_HEADERS): INSTALL_HEADERS = $${PREFIX}/include
33 |
34 | # plugins
35 | !no_bundle_deploy:win32:isEmpty(INSTALL_PLUGINS): INSTALL_PLUGINS = $$INSTALL_BINS
36 | else:isEmpty(INSTALL_PLUGINS): INSTALL_PLUGINS = $${PREFIX}/plugins
37 |
38 | # translations
39 | !no_bundle_deploy:android:isEmpty(INSTALL_TRANSLATIONS): INSTALL_TRANSLATIONS = /assets/translations
40 | else:isEmpty(INSTALL_TRANSLATIONS): INSTALL_TRANSLATIONS = $${PREFIX}/translations
41 |
42 | # share
43 | isEmpty(INSTALL_SHARE): INSTALL_SHARE = $${PREFIX}/share
44 | }
45 |
46 | auto_lrelease: PRE_TARGETDEPS += lrelease
47 | android: CONFIG += no_headers_install
48 |
--------------------------------------------------------------------------------
/webapp/qwasmsettings.cpp:
--------------------------------------------------------------------------------
1 | #include "qwasmsettings.h"
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 | using namespace emscripten;
8 |
9 | QSettings::Format QWasmSettings::registerFormat()
10 | {
11 | const auto format = QSettings::registerFormat(QStringLiteral("wasmconf"),
12 | &QWasmSettings::readWasmSettings,
13 | &QWasmSettings::writeWasmSettings,
14 | Qt::CaseSensitive);
15 | QSettings::setPath(format, QSettings::UserScope, QDir::tempPath());
16 | QSettings::setPath(format, QSettings::SystemScope, QDir::tempPath());
17 | QSettings::setDefaultFormat(format);
18 |
19 | QSettings mPathOrigin;
20 | prepareFile(mPathOrigin.fileName());
21 | return format;
22 | }
23 |
24 | void QWasmSettings::prepareFile(const QString &path)
25 | {
26 | QFileInfo{path}.dir().mkpath(QStringLiteral("."));
27 | QFile sFile{path};
28 | if(!sFile.open(QIODevice::WriteOnly)) {
29 | qWarning() << "QWasmSettings: Failed to prepare path"
30 | << path << "with error:" << qUtf8Printable(sFile.errorString());
31 | return;
32 | }
33 |
34 | sFile.write(QUuid::createUuid().toByteArray());
35 | sFile.close();
36 | }
37 |
38 | bool QWasmSettings::readWasmSettings(QIODevice &device, QSettings::SettingsMap &map)
39 | {
40 | Q_UNUSED(device);
41 |
42 | auto store = val::global("localStorage");
43 | if(store.isNull())
44 | return false;
45 |
46 | const auto keyCount = store["length"].as();
47 | for(auto i = 0; i < keyCount; ++i) {
48 | const auto key = store.call("key", i);
49 | const auto value = store.call("getItem", key).as();
50 | map.insert(QString::fromStdString(key),
51 | QString::fromStdString(value));
52 | }
53 |
54 | return true;
55 | }
56 |
57 | bool QWasmSettings::writeWasmSettings(QIODevice &device, const QSettings::SettingsMap &map)
58 | {
59 | auto store = val::global("localStorage");
60 | if(store.isNull())
61 | return false;
62 |
63 | store.call("clear");
64 | for(auto it = map.constBegin(); it != map.constEnd(); ++it) {
65 | store.call("setItem",
66 | it.key().toStdString(),
67 | it.value().toString().toStdString());
68 | }
69 |
70 | device.write(QUuid::createUuid().toByteArray());
71 | return true;
72 | }
73 |
--------------------------------------------------------------------------------
/clients/widgets/passconnectorpage.cpp:
--------------------------------------------------------------------------------
1 | #include "passconnectorpage.h"
2 | #include "ui_passconnectorpage.h"
3 | #include
4 |
5 | PassConnectorPage::PassConnectorPage(QtMvvm::ViewModel *viewModel, QWidget *parent) :
6 | QWizardPage{parent},
7 | _viewModel{static_cast(viewModel)},
8 | _ui{new Ui::PassConnectorPage{}}
9 | {
10 | _ui->setupUi(this);
11 | setFinalPage(true);
12 |
13 | _ui->channelIDLineEdit->setValidator(_viewModel->channelIdValidator());
14 | _ui->passphraseLineEdit->addAction(_ui->actionGenerate_random_passphrase, QLineEdit::TrailingPosition);
15 | _ui->passphraseLineEdit->addAction(_ui->actionToggle_passphrase_visibility, QLineEdit::TrailingPosition);
16 |
17 | connect(_ui->actionToggle_passphrase_visibility, &QAction::triggered,
18 | this, &PassConnectorPage::toggleVisible);
19 | connect(_ui->actionGenerate_random_passphrase, &QAction::triggered,
20 | _viewModel, &PassConnectorViewModel::generateRandomPassphrase);
21 |
22 | QtMvvm::bind(_viewModel, "channelIdStr",
23 | _ui->channelIDLineEdit, "text",
24 | QtMvvm::Binding::OneWayToViewModel);
25 | QtMvvm::bind(_viewModel, "passphrase",
26 | _ui->passphraseLineEdit, "text",
27 | QtMvvm::Binding::TwoWay,
28 | nullptr,
29 | "editingFinished()");
30 | connect(_viewModel, &PassConnectorViewModel::channelIdChanged,
31 | this, &PassConnectorPage::appIdChanged);
32 | appIdChanged();
33 | }
34 |
35 | bool PassConnectorPage::validatePage()
36 | {
37 | return _viewModel->transfer();
38 | }
39 |
40 | bool PassConnectorPage::isComplete() const
41 | {
42 | return _viewModel->isValid();
43 | }
44 |
45 | void PassConnectorPage::appIdChanged()
46 | {
47 | auto pal = palette();
48 | if(_viewModel->isValid()) {
49 | _ui->statusLabel->setText(tr("Channel-ID is valid"));
50 | pal.setColor(QPalette::WindowText, Qt::darkGreen);
51 | _ui->statusLabel->setPalette(pal);
52 | } else {
53 | _ui->statusLabel->setText(tr("Channel-ID is invalid"));
54 | pal.setColor(QPalette::WindowText, Qt::darkRed);
55 | _ui->statusLabel->setPalette(pal);
56 | }
57 | emit completeChanged();
58 | }
59 |
60 | void PassConnectorPage::toggleVisible(bool visible)
61 | {
62 | _ui->passphraseLineEdit->setEchoMode(visible ? QLineEdit::Normal : QLineEdit::Password);
63 | }
64 |
65 | PassConnectorPage::~PassConnectorPage() = default;
66 |
--------------------------------------------------------------------------------
/webapp/qrencoder.cpp:
--------------------------------------------------------------------------------
1 | #include "qrencoder.h"
2 | #include
3 | #include
4 | #include
5 | using namespace CryptoPP;
6 |
7 | QrEncoder::QrEncoder(QObject *parent) :
8 | IEncoder{parent}
9 | {
10 | registerEncoder(EncryptedData::DataMode::QrCode, this);
11 | }
12 |
13 | DataEncryptor::ECCCurve QrEncoder::curve() const
14 | {
15 | return _curve;
16 | }
17 |
18 | QUuid QrEncoder::channelId() const
19 | {
20 | return _channelId;
21 | }
22 |
23 | QString QrEncoder::qrData() const
24 | {
25 | try {
26 | if(!_privKey)
27 | return {};
28 |
29 | if(_pubKey.isNull()) {
30 | _qrData.clear();
31 | _pubKey = encryptor()->serializePublicKey(_privKey);
32 | }
33 |
34 | if(_qrData.isNull())
35 | _qrData = QString::fromUtf8(KPTLib::encode(QrData{_channelId, _pubKey}, true));
36 |
37 | return _qrData;
38 | } catch(std::exception &e) {
39 | qCritical() << "Failed to obtain public key from private key with error:"
40 | << e.what();
41 | return {};
42 | }
43 | }
44 |
45 | bool QrEncoder::isValid() const
46 | {
47 | return _privKey && !_channelId.isNull();
48 | }
49 |
50 | void QrEncoder::classBegin()
51 | {
52 | _blocked = true;
53 | }
54 |
55 | void QrEncoder::componentComplete()
56 | {
57 | _blocked = false;
58 | recreateKeys();
59 | }
60 |
61 | void QrEncoder::recreateKeys()
62 | {
63 | if(_blocked)
64 | return;
65 |
66 | try {
67 | //NOTE make async
68 | _privKey.clear();
69 | _pubKey.clear();
70 | _qrData.clear();
71 | emit qrDataChanged({});
72 | _privKey = encryptor()->generateAsymKey(rng(), _curve);
73 | emit qrDataChanged({});
74 | } catch(std::exception &e) {
75 | qCritical() << "Failed to generate new private key with error:"
76 | << e.what();
77 | }
78 | }
79 |
80 | void QrEncoder::setCurve(DataEncryptor::ECCCurve curve)
81 | {
82 | if (_curve == curve)
83 | return;
84 |
85 | _curve = curve;
86 | emit curveChanged(_curve);
87 | recreateKeys();
88 | }
89 |
90 | void QrEncoder::setChannelId(QUuid channelId)
91 | {
92 | if (_channelId == channelId)
93 | return;
94 |
95 | _channelId = std::move(channelId);
96 | _qrData.clear();
97 | emit qrDataChanged({});
98 | }
99 |
100 | QByteArray QrEncoder::decryptData(const QByteArray &keyInfo, const QByteArray &iv, const QByteArray &data) const
101 | {
102 | const auto secretKey = encryptor()->decryptSecretKey(rng(), keyInfo, _privKey);
103 | return encryptor()->decryptSymmetric(data, secretKey, iv);
104 | }
105 |
--------------------------------------------------------------------------------
/3rdparty/cryptopp/cryptopp.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = lib
2 |
3 | load(qt_build_config)
4 | CONFIG += staticlib exceptions c++14
5 | CONFIG -= qt
6 |
7 | TARGET = $$qtLibraryTarget(qtcryptopp)
8 |
9 | QMAKE_CXXFLAGS_RELEASE += "-DNDEBUG"
10 |
11 | win32:!win32-g++ {
12 | QMAKE_CXXFLAGS += /arch:AVX2
13 | DEFINES += CRYPTOPP_DISABLE_ASM #TODO reenable again later
14 | cross_compile: DEFINES += NO_OS_DEPENDENCE
15 | } else:wasm {
16 | QMAKE_CXXFLAGS += -msse4.1 -mssse3
17 | } else {
18 | # based on https://github.com/KayEss/fost-crypto/blob/master/CMakeLists.txt
19 | QMAKE_CXXFLAGS += -Wno-keyword-macro -Wno-unused-const-variable -Wno-unused-private-field
20 |
21 | !isEmpty(ANDROID_TARGET_ARCH) {
22 | message("Building for android arch $$ANDROID_TARGET_ARCH")
23 | INCLUDEPATH += $$(ANDROID_NDK_ROOT)/sources/android/cpufeatures
24 | SOURCES += $$(ANDROID_NDK_ROOT)/sources/android/cpufeatures/cpu-features.c
25 |
26 | equals(ANDROID_TARGET_ARCH, armeabi-v7a) {
27 | QMAKE_CXXFLAGS -= -mfpu=vfp
28 | QMAKE_CXXFLAGS += -mfpu=neon
29 | } else:equals(ANDROID_TARGET_ARCH, arm64-v8a) {
30 | # nothing to be done
31 | } else:equals(ANDROID_TARGET_ARCH, x86) {
32 | QMAKE_CXXFLAGS += -maes -mpclmul -msha -msse4.1 -msse4.2 -mssse3
33 | # Do this for Android builds for now as the NDK is broken
34 | DEFINES += CRYPTOPP_DISABLE_ASM
35 | warning("Disabled x86 crypto ASM")
36 | }
37 | } else {
38 | # assume "normal" x86 arch
39 | message("Building for host x86 arch")
40 | QMAKE_CXXFLAGS += -maes -mpclmul -msha -msse4.1 -msse4.2 -mssse3
41 | }
42 | }
43 |
44 | # Input
45 | HEADERS += $$files(src/*.h)
46 |
47 | SOURCES += $$files(src/*.cpp)
48 |
49 | SOURCES -= \
50 | src/bench1.cpp \
51 | src/bench2.cpp \
52 | src/datatest.cpp \
53 | src/dlltest.cpp \
54 | src/pch.cpp \
55 | src/regtest1.cpp \
56 | src/regtest2.cpp \
57 | src/regtest3.cpp \
58 | src/test.cpp \
59 | src/validat0.cpp \
60 | src/validat1.cpp \
61 | src/validat2.cpp \
62 | src/validat3.cpp \
63 | src/validat4.cpp \
64 | src/TestScripts/cryptest-coverity.cpp
65 |
66 | DISTFILES += cryptopp.pri
67 |
68 | load(qt_build_paths)
69 |
70 | HEADER_INSTALL_DIR = "$$shadowed($$SRC_ROOT_DIR)/include/cryptopp"
71 | !ReleaseBuild|!DebugBuild {
72 | !mkpath($$HEADER_INSTALL_DIR):error("Failed to create cryptopp header dir: $$HEADER_INSTALL_DIR")
73 | for(hdr, HEADERS):!system($$QMAKE_QMAKE -install qinstall "$$PWD/$$hdr" "$$HEADER_INSTALL_DIR/$$basename(hdr)"):error("Failed to install header file: $$hdr")
74 | }
75 |
76 | INCLUDEPATH += "$$MODULE_BASE_OUTDIR/include"
77 |
--------------------------------------------------------------------------------
/clients/core/clienttransferservice.h:
--------------------------------------------------------------------------------
1 | #ifndef CLIENTTRANSFERSERVICE_H
2 | #define CLIENTTRANSFERSERVICE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include