mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 02:36:34 +01:00
[GnomeKeyring] Added plugin for storing passwords in gnome-keyring.
This commit is contained in:
parent
74edb1efa1
commit
8da362b119
20
src/plugins/GnomeKeyringPasswords/GnomeKeyringPasswords.pro
Normal file
20
src/plugins/GnomeKeyringPasswords/GnomeKeyringPasswords.pro
Normal file
@ -0,0 +1,20 @@
|
||||
include(../../defines.pri)
|
||||
|
||||
!mac:unix:contains(DEFINES, "GNOME_INTEGRATION"):system(pkg-config --exists gnome-keyring-1) {
|
||||
TARGET = $$qtLibraryTarget(GnomeKeyringPasswords)
|
||||
|
||||
SOURCES += gnomekeyringplugin.cpp \
|
||||
gnomekeyringpasswordbackend.cpp
|
||||
|
||||
HEADERS += gnomekeyringplugin.h \
|
||||
gnomekeyringpasswordbackend.h
|
||||
|
||||
RESOURCES += gnomekeyringpasswords.qrc
|
||||
|
||||
TRANSLATIONS = translations/cs_CZ.ts \
|
||||
|
||||
LIBS += $$system(pkg-config --libs gnome-keyring-1)
|
||||
QMAKE_CXXFLAGS += $$system(pkg-config --cflags gnome-keyring-1)
|
||||
}
|
||||
|
||||
include(../../plugins.pri)
|
BIN
src/plugins/GnomeKeyringPasswords/data/icon.png
Normal file
BIN
src/plugins/GnomeKeyringPasswords/data/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,283 @@
|
||||
/* ============================================================
|
||||
* GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
* ============================================================ */
|
||||
#include "gnomekeyringpasswordbackend.h"
|
||||
#include "gnomekeyringplugin.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
|
||||
extern "C" {
|
||||
#include "gnome-keyring.h"
|
||||
}
|
||||
|
||||
static QByteArray urlEncodePassword(const QString &password)
|
||||
{
|
||||
QByteArray encodedPass = QUrl::toPercentEncoding(password);
|
||||
encodedPass.replace(' ', '+');
|
||||
return encodedPass;
|
||||
}
|
||||
|
||||
static PasswordEntry createEntry(GnomeKeyringFound* item)
|
||||
{
|
||||
PasswordEntry entry;
|
||||
entry.id = item->item_id;
|
||||
entry.password = item->secret;
|
||||
|
||||
for (unsigned i = 0; i < item->attributes->len; ++i) {
|
||||
GnomeKeyringAttribute attr = g_array_index(item->attributes, GnomeKeyringAttribute, i);
|
||||
|
||||
if (strcmp(attr.name, "host") == 0) {
|
||||
entry.host = attr.value.string;
|
||||
}
|
||||
else if (strcmp(attr.name, "username") == 0) {
|
||||
entry.username = attr.value.string;
|
||||
}
|
||||
else if (strcmp(attr.name, "data") == 0) {
|
||||
entry.data = attr.value.string;
|
||||
}
|
||||
else if (strcmp(attr.name, "updated") == 0) {
|
||||
entry.updated = attr.value.integer;
|
||||
}
|
||||
}
|
||||
|
||||
entry.data.replace(QByteArray("___PASSWORD-VALUE___"), urlEncodePassword(entry.password));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static GnomeKeyringAttributeList* createAttributes(const PasswordEntry &entry)
|
||||
{
|
||||
GnomeKeyringAttributeList* attributes = gnome_keyring_attribute_list_new();
|
||||
|
||||
gnome_keyring_attribute_list_append_string(attributes, "application", "QupZilla");
|
||||
|
||||
QByteArray value = entry.username.toUtf8();
|
||||
gnome_keyring_attribute_list_append_string(attributes, "username", value.constData());
|
||||
|
||||
value = entry.data;
|
||||
value.replace(urlEncodePassword(entry.password), "___PASSWORD-VALUE___");
|
||||
gnome_keyring_attribute_list_append_string(attributes, "data", value.constData());
|
||||
|
||||
value = entry.host.toUtf8();
|
||||
gnome_keyring_attribute_list_append_string(attributes, "host", value.constData());
|
||||
|
||||
gnome_keyring_attribute_list_append_uint32(attributes, "updated", entry.updated);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
GnomeKeyringPasswordBackend::GnomeKeyringPasswordBackend()
|
||||
: PasswordBackend()
|
||||
, m_loaded(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString GnomeKeyringPasswordBackend::name() const
|
||||
{
|
||||
return GnomeKeyringPlugin::tr("Gnome Keyring");
|
||||
}
|
||||
|
||||
QVector<PasswordEntry> GnomeKeyringPasswordBackend::getEntries(const QUrl &url)
|
||||
{
|
||||
initialize();
|
||||
|
||||
const QString &host = PasswordManager::createHost(url);
|
||||
|
||||
QVector<PasswordEntry> list;
|
||||
|
||||
foreach (const PasswordEntry &entry, m_allEntries) {
|
||||
if (entry.host == host) {
|
||||
list.append(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort to prefer last updated entries
|
||||
qSort(list.begin(), list.end());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QVector<PasswordEntry> GnomeKeyringPasswordBackend::getAllEntries()
|
||||
{
|
||||
initialize();
|
||||
|
||||
return m_allEntries;
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::addEntry(const PasswordEntry &entry)
|
||||
{
|
||||
initialize();
|
||||
|
||||
PasswordEntry stored = entry;
|
||||
stored.updated = QDateTime::currentDateTime().toTime_t();
|
||||
|
||||
guint32 itemId;
|
||||
GnomeKeyringAttributeList* attributes = createAttributes(stored);
|
||||
|
||||
QByteArray pass = stored.password.toUtf8();
|
||||
QByteArray host = stored.host.toUtf8();
|
||||
|
||||
GnomeKeyringResult result = gnome_keyring_item_create_sync(GNOME_KEYRING_DEFAULT,
|
||||
GNOME_KEYRING_ITEM_GENERIC_SECRET,
|
||||
host.constData(),
|
||||
attributes,
|
||||
pass.constData(),
|
||||
TRUE, // Update if exists
|
||||
&itemId);
|
||||
|
||||
gnome_keyring_attribute_list_free(attributes);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::addEntry Cannot add entry to keyring!";
|
||||
}
|
||||
|
||||
stored.id = itemId;
|
||||
|
||||
m_allEntries.append(stored);
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::updateEntry(const PasswordEntry &entry)
|
||||
{
|
||||
initialize();
|
||||
|
||||
// Update item attributes
|
||||
GnomeKeyringAttributeList* attributes = createAttributes(entry);
|
||||
|
||||
GnomeKeyringResult result = gnome_keyring_item_set_attributes_sync(GNOME_KEYRING_DEFAULT,
|
||||
entry.id.toUInt(),
|
||||
attributes);
|
||||
|
||||
gnome_keyring_attribute_list_free(attributes);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot updated entry attributes in keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
// Update secret
|
||||
GnomeKeyringItemInfo* info;
|
||||
result = gnome_keyring_item_get_info_full_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(),
|
||||
GNOME_KEYRING_ITEM_INFO_SECRET, &info);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot get entry info from keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray pass = entry.password.toUtf8();
|
||||
gnome_keyring_item_info_set_secret(info, pass.constData());
|
||||
|
||||
result = gnome_keyring_item_set_info_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt(), info);
|
||||
|
||||
gnome_keyring_item_info_free(info);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::updateEntry Cannot set entry info in keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
int index = m_allEntries.indexOf(entry);
|
||||
|
||||
if (index > -1) {
|
||||
m_allEntries[index] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::updateLastUsed(PasswordEntry &entry)
|
||||
{
|
||||
initialize();
|
||||
|
||||
entry.updated = QDateTime::currentDateTime().toTime_t();
|
||||
|
||||
GnomeKeyringAttributeList* attributes = createAttributes(entry);
|
||||
|
||||
GnomeKeyringResult result = gnome_keyring_item_set_attributes_sync(GNOME_KEYRING_DEFAULT,
|
||||
entry.id.toUInt(),
|
||||
attributes);
|
||||
|
||||
gnome_keyring_attribute_list_free(attributes);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::updateLastUsed Cannot updated entry in keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
int index = m_allEntries.indexOf(entry);
|
||||
|
||||
if (index > -1) {
|
||||
m_allEntries[index] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::removeEntry(const PasswordEntry &entry)
|
||||
{
|
||||
initialize();
|
||||
|
||||
GnomeKeyringResult result = gnome_keyring_item_delete_sync(GNOME_KEYRING_DEFAULT, entry.id.toUInt());
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::removeEntry Cannot remove entry from keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
int index = m_allEntries.indexOf(entry);
|
||||
|
||||
if (index > -1) {
|
||||
m_allEntries.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::removeAll()
|
||||
{
|
||||
initialize();
|
||||
|
||||
foreach (const PasswordEntry &entry, m_allEntries) {
|
||||
removeEntry(entry);
|
||||
}
|
||||
|
||||
m_allEntries.clear();
|
||||
}
|
||||
|
||||
void GnomeKeyringPasswordBackend::initialize()
|
||||
{
|
||||
if (m_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
GList* found;
|
||||
GnomeKeyringResult result = gnome_keyring_find_itemsv_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET, &found,
|
||||
"application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, "QupZilla",
|
||||
NULL);
|
||||
|
||||
if (result != GNOME_KEYRING_RESULT_OK && result != GNOME_KEYRING_RESULT_NO_MATCH) {
|
||||
qWarning() << "GnomeKeyringPasswordBackend::initialize Cannot read items from keyring!";
|
||||
return;
|
||||
}
|
||||
|
||||
GList* tmp = found;
|
||||
|
||||
while (tmp) {
|
||||
GnomeKeyringFound* item = (GnomeKeyringFound*) tmp->data;
|
||||
m_allEntries.append(createEntry(item));
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
gnome_keyring_found_list_free(found);
|
||||
|
||||
m_loaded = true;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* ============================================================
|
||||
* GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
* ============================================================ */
|
||||
#ifndef GNOMEKEYRINGPASSWORDBACKEND_H
|
||||
#define GNOMEKEYRINGPASSWORDBACKEND_H
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#include "passwordbackends/passwordbackend.h"
|
||||
#include "passwordmanager.h"
|
||||
|
||||
class GnomeKeyringPasswordBackend : public PasswordBackend
|
||||
{
|
||||
public:
|
||||
explicit GnomeKeyringPasswordBackend();
|
||||
|
||||
QString name() const;
|
||||
|
||||
QVector<PasswordEntry> getEntries(const QUrl &url);
|
||||
QVector<PasswordEntry> getAllEntries();
|
||||
|
||||
void addEntry(const PasswordEntry &entry);
|
||||
void updateEntry(const PasswordEntry &entry);
|
||||
void updateLastUsed(PasswordEntry &entry);
|
||||
|
||||
void removeEntry(const PasswordEntry &entry);
|
||||
void removeAll();
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
|
||||
bool m_loaded;
|
||||
QVector<PasswordEntry> m_allEntries;
|
||||
};
|
||||
|
||||
#endif // GNOMEKEYRINGPASSWORDBACKEND_H
|
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/gkp">
|
||||
<file>data/icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
66
src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp
Normal file
66
src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/* ============================================================
|
||||
* GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
* ============================================================ */
|
||||
#include "gnomekeyringplugin.h"
|
||||
#include "gnomekeyringpasswordbackend.h"
|
||||
#include "pluginproxy.h"
|
||||
#include "qupzilla.h"
|
||||
|
||||
#include <QTranslator>
|
||||
|
||||
GnomeKeyringPlugin::GnomeKeyringPlugin()
|
||||
: QObject()
|
||||
, m_backend(0)
|
||||
{
|
||||
}
|
||||
|
||||
PluginSpec GnomeKeyringPlugin::pluginSpec()
|
||||
{
|
||||
PluginSpec spec;
|
||||
spec.name = "Gnome Keyring Passwords";
|
||||
spec.info = "Gnome Keyring password backend";
|
||||
spec.description = "Provides support for storing passwords in gnome-keyring";
|
||||
spec.version = "0.1.0";
|
||||
spec.author = "David Rosca <nowrep@gmail.com>";
|
||||
spec.icon = QPixmap(":gkp/data/icon.png");
|
||||
spec.hasSettings = false;
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
void GnomeKeyringPlugin::init(const QString &sPath)
|
||||
{
|
||||
Q_UNUSED(sPath);
|
||||
|
||||
m_backend = new GnomeKeyringPasswordBackend;
|
||||
QZ_REGISTER_PASSWORD_BACKEND("GnomeKeyring", m_backend);
|
||||
}
|
||||
|
||||
void GnomeKeyringPlugin::unload()
|
||||
{
|
||||
QZ_UNREGISTER_PASSWORD_BACKEND(m_backend);
|
||||
delete m_backend;
|
||||
}
|
||||
|
||||
bool GnomeKeyringPlugin::testPlugin()
|
||||
{
|
||||
return (QupZilla::VERSION == QLatin1String("1.5.0"));
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
Q_EXPORT_PLUGIN2(GnomeKeyringPasswords, GnomeKeyringPlugin)
|
||||
#endif
|
47
src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h
Normal file
47
src/plugins/GnomeKeyringPasswords/gnomekeyringplugin.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* ============================================================
|
||||
* GnomeKeyringPasswords - gnome-keyring support plugin for QupZilla
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
* ============================================================ */
|
||||
#ifndef GNOMEKEYRINGPLUGIN_H
|
||||
#define GNOMEKEYRINGPLUGIN_H
|
||||
|
||||
#include "plugininterface.h"
|
||||
|
||||
class GnomeKeyringPasswordBackend;
|
||||
|
||||
class GnomeKeyringPlugin : public QObject, public PluginInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.GnomeKeyringPasswords")
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit GnomeKeyringPlugin();
|
||||
PluginSpec pluginSpec();
|
||||
|
||||
void init(const QString &sPath);
|
||||
void unload();
|
||||
bool testPlugin();
|
||||
|
||||
private:
|
||||
GnomeKeyringPasswordBackend* m_backend;
|
||||
|
||||
};
|
||||
|
||||
#endif // GNOMEKEYRINGPLUGIN_H
|
27
src/plugins/GnomeKeyringPasswords/test.cpp
Normal file
27
src/plugins/GnomeKeyringPasswords/test.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
#include "gnome-keyring.h"
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
guint32 itemId;
|
||||
GnomeKeyringAttributeList* attributes = gnome_keyring_attribute_list_new();
|
||||
|
||||
gnome_keyring_attribute_list_append_string(attributes, "key", "value");
|
||||
|
||||
GnomeKeyringResult result = gnome_keyring_item_create_sync(GNOME_KEYRING_DEFAULT,
|
||||
GNOME_KEYRING_ITEM_GENERIC_SECRET,
|
||||
"display-name",
|
||||
attributes,
|
||||
"passwrd-123",
|
||||
TRUE, // Update if exists
|
||||
&itemId);
|
||||
|
||||
if (result == GNOME_KEYRING_RESULT_OK) {
|
||||
printf("OK, id=%d\n", itemId);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
12
src/plugins/GnomeKeyringPasswords/translations/cs_CZ.ts
Normal file
12
src/plugins/GnomeKeyringPasswords/translations/cs_CZ.ts
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.0" language="cs_CZ">
|
||||
<context>
|
||||
<name>GnomeKeyringPlugin</name>
|
||||
<message>
|
||||
<location filename="../gnomekeyringpasswordbackend.cpp" line="92"/>
|
||||
<source>Gnome Keyring</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
12
src/plugins/GnomeKeyringPasswords/translations/empty.ts
Normal file
12
src/plugins/GnomeKeyringPasswords/translations/empty.ts
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.0">
|
||||
<context>
|
||||
<name>GnomeKeyringPlugin</name>
|
||||
<message>
|
||||
<location filename="../gnomekeyringpasswordbackend.cpp" line="92"/>
|
||||
<source>Gnome Keyring</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
Loading…
Reference in New Issue
Block a user