KDE + GNOME: moved keyring/kwallet and KDE init into modules

The platform specific code which is of no value unless you run a
specific desktop now gets compiled as part of shared libraries, just
like the storage backends. The advantage is that the rest of
SyncEvolution keeps running even if one of these shared libraries
cannot be loaded due to missing depdendencies. syncevolution.org
packages will not declared these dependencies, to allow installing
each package without forcing the installation of unwanted libraries.
Distros can package the platform code separately.

Another advantage is reduced code duplication (password load/store
was duplicated in command line and D-Bus server).

Technically this uses almost the same mechnism as loadable sync
sources. The code resides in src/backends/[kde|gnome], where the
autotool magic finds the *Register.cpp files automatically and
includes them into executables. These files contain global singletons
which, when initialized, connect platform specific code to new signals
in the core (init, password load/save).

The actual code is in the backend libraries. Because
SE_ARG_ENABLE_BACKEND() is not used (in favor of the traditional
enable macros), linking against these libs must be set up by adding
them to the (now slightly misnamed) SYNCSOURCES variable in the
configure fragments.
This commit is contained in:
Patrick Ohly 2012-03-06 09:24:15 +01:00
parent 962cf4be1e
commit eafc49cb35
22 changed files with 725 additions and 499 deletions

View File

@ -468,84 +468,6 @@ AS_IF([test "x$with_gio_gdbus" = "xyes"],
AC_DEFINE(NEED_DBUS_WATCH_GET_UNIX_FD, 1,
[Define to 1 if you need the dbus_watch_get_unix_fd() function.]))])
PKG_CHECK_MODULES(KEYRING, [gnome-keyring-1], HAVE_KEYRING=yes, HAVE_KEYRING=no)
AC_ARG_ENABLE(gnome-keyring,
AS_HELP_STRING([--enable-gnome-keyring],
[enables or disables support for the GNOME keyring; default is on if development files are available]),
[enable_gnome_keyring="$enableval"
test "$enable_gnome_keyring" = "yes" || test "$enable_gnome_keyring" = "no" || AC_MSG_ERROR([invalid value for --enable-gnome-keyring: $enable_gnome_keyring])
test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([gnome-keyring-1 pkg not found, needed for --enable-gnome-keyring])],
enable_gnome_keyring="$HAVE_KEYRING")
if test $enable_gnome_keyring = "yes"; then
AC_DEFINE(USE_GNOME_KEYRING, 1, [define if gnome keyring should be used in dbus service])
PKG_CHECK_MODULES([KEYRING_2_20], [gnome-keyring-1 >= 2.20 ], KEYRING220=yes, KEYRING220=no)
if test $KEYRING220 = "yes"; then
AC_DEFINE(GNOME_KEYRING_220, 1, [define if gnome keyring version is above 2.20])
fi
fi
## Begin KWallet ##############################
# first check for qmake-qt4, because qmake may point to qmake-qt3.
AC_CHECK_PROGS([QMAKE], [qmake-qt4 qmake])
if test "x$QMAKE" != 'x'
then
AC_PATH_PROG([KDE4_CONFIG], [kde4-config], [no])
if test "x$KDE4_CONFIG" != 'xno'
then
KDEKWALLETFOUND=yes
if ! test "$KDE_KWALLET_CFLAGS"; then
KDE_KWALLET_CFLAGS="-I`$KDE4_CONFIG --path include` -I`$KDE4_CONFIG --path include`/KDE `pkg-config --cflags QtDBus QtCore`"
fi
if ! test "$KDE_KWALLET_LIBS"; then
KDE_KWALLET_LIBS="-lkdeui -lkdecore -L`kde4-config --install lib` `pkg-config --libs QtDBus QtCore`"
fi
AC_LANG_PUSH(C++)
old_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $KDE_KWALLET_CFLAGS"
AC_CHECK_HEADERS(kwallet.h, [], [KDEKWALLETFOUND=no])
CPPFLAGS="$old_CPPFLAGS"
AC_LANG_POP(C++)
else
KDEKWALLETFOUND=no
fi
else
KDEKWALLETFOUND=no
fi
# In contrast to the GNOME KEYRING, the KWallet is
# currently considered optional. "configure" will never enable
# by default, because that is a change that might not be
# expected by traditional users.
AC_ARG_ENABLE(kwallet,
AS_HELP_STRING([--enable-kwallet], [enable access to KWallet]),
[use_kde_kwallet="$enableval"
test $KDEKWALLETFOUND = "yes" || test "$use_kde_kwallet" = "no" || AC_MSG_ERROR([kwallet.pc not found. Install it to compile with the KWallet enabled.])],
[use_kde_kwallet="no"])
if test "$use_kde_kwallet" = "yes"; then
# conditional compilation in preprocessor
AC_DEFINE(USE_KDE_KWALLET, 1, [KWallet available])
# TODO: KWallet needs Qt. Enable the Qt check in
# configure-post.in, otherwise it fails to compiler
# when none of the backends ask for Qt.
else
# avoid unneeded dependencies on KWallet
KDE_KWALLET_CFLAGS=
KDE_KWALLET_LIBS=
fi
AC_SUBST(KDE_KWALLET_LIBS)
AC_SUBST(KDE_KWALLET_CFLAGS)
# conditional compilation in make
AM_CONDITIONAL([USE_KDE_KWALLET], [test "$use_kde_kwallet" = "yes"])
## End KWallet ################################
if test $enable_dbus_service = "yes"; then
if test -z "$XSLT"; then
AC_MSG_ERROR([xsltproc not found, is required for D-Bus service])
@ -600,8 +522,6 @@ AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)
AC_SUBST(KEYRING_CFLAGS)
AC_SUBST(KEYRING_LIBS)
AC_SUBST(LIBNOTIFY_CFLAGS)
AC_SUBST(LIBNOTIFY_LIBS)
AC_SUBST(LIBEXECDIR)

View File

@ -18,15 +18,6 @@
*/
#include "CmdlineSyncClient.h"
#ifdef USE_GNOME_KEYRING
extern "C" {
#include <gnome-keyring.h>
}
#endif
#ifdef USE_KDE_KWALLET
#include <kwallet.h>
#endif
#include <syncevo/declarations.h>
SE_BEGIN_CXX
@ -40,15 +31,6 @@ CmdlineSyncClient::CmdlineSyncClient(const string &server,
m_keyring(useKeyring)
{
}
/**
* GNOME keyring distinguishes between empty and unset
* password keys. This function returns NULL for an
* empty std::string.
*/
inline const char *passwdStr(const std::string &str)
{
return str.empty() ? NULL : str.c_str();
}
string CmdlineSyncClient::askPassword(const string &passwordName,
const string &descr,
@ -56,74 +38,19 @@ string CmdlineSyncClient::askPassword(const string &passwordName,
{
string password;
#ifdef USE_KDE_KWALLET
/** here we use server sync url without protocol prefix and
* user account name as the key in the keyring */
/* Also since the KWallet's API supports only storing (key,passowrd)
* or Map<QString,QString> , the former is used */
bool isKde = true;
#ifdef USE_GNOME_KEYRING
//When Both GNOME KEYRING and KWALLET are available, Check if this is a KDE Session
//and Call KWallet if it is. else pick Gnome Keyring by default
if (!getenv("KDE_FULL_SESSION")) {
isKde = false;
// try to use keyring, if allowed
if (m_keyring &&
GetLoadPasswordSignal()(passwordName, descr, key, password)) {
// succcess
return password;
}
#endif
if (isKde && m_keyring) {
QString walletPassword;
const QString walletKey = QString::fromStdString(key.user + ',' +
key.domain + ',' + key.server + ',' + key.object + ',' +
key.protocol + ',' + key.authtype + ',') + QString::number(key.port);
// TODO: move SyncContext::askPassword here
const QString wallet_name = KWallet::Wallet::NetworkWallet();
//QString folder = QString::fromUtf8("Syncevolution");
const QLatin1String folder("Syncevolution");
if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)){
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous);
if (wallet && wallet->setFolder(folder) &&
wallet->readPassword(walletKey, walletPassword) == 0) {
return walletPassword.toStdString();
}
}
}
#endif
#ifdef USE_GNOME_KEYRING
/** here we use server sync url without protocol prefix and
* user account name as the key in the keyring */
if(m_keyring) {
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
GnomeKeyringResult result;
GList* list;
result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
&list);
// if find password stored in gnome keyring
if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
GnomeKeyringNetworkPasswordData *key_data;
key_data = (GnomeKeyringNetworkPasswordData*)list->data;
password = key_data->password;
gnome_keyring_network_password_list_free(list);
return password;
}
}
//if not found, then ask user to interactively input password
#endif
/** if not built with secrets support, directly ask user to
* input password */
/**
* if not built with secrets support or that support failed,
* directly ask user to input password
*/
password = SyncContext::askPassword(passwordName, descr, key);
return password;
}
@ -132,97 +59,22 @@ bool CmdlineSyncClient::savePassword(const string &passwordName,
const string &password,
const ConfigPasswordKey &key)
{
#ifdef USE_KDE_KWALLET
bool isKde = true;
#ifdef USE_GNOME_KEYRING
// When both GNOME KEYRING and KWALLET are available, check if
// this is a KDE Session and call
if (!getenv("KDE_FULL_SESSION")) {
isKde = false;
}
#endif
if (m_keyring && isKde) {
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
// write password to keyring
const QString walletKey = QString::fromStdString(key.user + ',' +
key.domain + ',' + key.server + ',' + key.object + ',' +
key.protocol + ',' + key.authtype + ',')+ QString::number(key.port);
const QString walletPassword = QString::fromStdString(password);
bool write_success = false;
const QString wallet_name = KWallet::Wallet::NetworkWallet();
const QLatin1String folder("Syncevolution");
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1,
KWallet::Wallet::Synchronous);
if (wallet) {
if (!wallet->hasFolder(folder)) {
wallet->createFolder(folder);
}
if (wallet->setFolder(folder) &&
wallet->writePassword(walletKey, walletPassword) == 0) {
write_success = true;
}
}
if (!write_success) {
SyncContext::throwError("Try to save " + passwordName + " in KWallet but got an error. ");
}
return write_success;
}
// use keyring?
if (m_keyring) {
SyncContext::throwError("Try to save " + passwordName +
" in KWallet but get an error. "
"This syncevolution binary was compiled without support for storing "
"passwords in a Wallet. Either store passwords in your configuration "
"files or enter them interactively on each program run.\n");
}
#endif
if (GetSavePasswordSignal()(passwordName, password, key)) {
// saved!
return true;
}
#ifdef USE_GNOME_KEYRING
if(m_keyring) {
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
guint32 itemId;
GnomeKeyringResult result;
// write password to keyring
result = gnome_keyring_set_network_password_sync(NULL,
passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
password.c_str(),
&itemId);
/* if set operation is failed */
if(result != GNOME_KEYRING_RESULT_OK) {
#ifdef GNOME_KEYRING_220
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. " + gnome_keyring_result_to_message(result));
#else
/** if gnome-keyring version is below 2.20, it doesn't support 'gnome_keyring_result_to_message'. */
stringstream value;
value << (int)result;
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. The gnome-keyring error code is " + value.str() + ".");
#endif
}
return true;
/* if no keyring support and it was requested, then raise an error */
SyncContext::throwError("Cannot save " + passwordName + " as requested. "
"This SyncEvolution binary was compiled without support for storing "
"passwords in a keyring or wallet, or none of the backends providing that "
"functionality were usable. Either store passwords in your configuration "
"files or enter them interactively on each program run.\n");
}
#endif
/* if no keyring support, raise the error */
if(m_keyring) {
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. " +
"This syncevolution binary was compiled without support for storing "
"passwords in a keyring. Either store passwords in your configuration "
"files or enter them interactively on each program run.\n");
}
// let config code store the password
return false;
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <config.h>
#ifdef USE_GNOME_KEYRING
extern "C" {
#include <gnome-keyring.h>
}
#include "GNOMEPlatform.h"
#include <syncevo/SyncContext.h>
#include <syncevo/SyncConfig.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
/**
* GNOME keyring distinguishes between empty and unset
* password keys. This function returns NULL for an
* empty std::string.
*/
inline const char *passwdStr(const std::string &str)
{
return str.empty() ? NULL : str.c_str();
}
bool GNOMELoadPasswordSlot(const std::string &passwordName,
const std::string &descr,
const ConfigPasswordKey &key,
std::string &password)
{
GnomeKeyringResult result;
GList* list;
result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
&list);
// if find password stored in gnome keyring
if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
GnomeKeyringNetworkPasswordData *key_data;
key_data = (GnomeKeyringNetworkPasswordData*)list->data;
password = key_data->password;
gnome_keyring_network_password_list_free(list);
return true;
}
// not found, ask user
return false;
}
bool GNOMESavePasswordSlot(const std::string &passwordName,
const std::string &password,
const ConfigPasswordKey &key)
{
guint32 itemId;
GnomeKeyringResult result;
// write password to keyring
result = gnome_keyring_set_network_password_sync(NULL,
passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
password.c_str(),
&itemId);
/* if set operation is failed */
if(result != GNOME_KEYRING_RESULT_OK) {
#ifdef GNOME_KEYRING_220
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. " + gnome_keyring_result_to_message(result));
#else
/** if gnome-keyring version is below 2.20, it doesn't support 'gnome_keyring_result_to_message'. */
stringstream value;
value << (int)result;
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. The gnome-keyring error code is " + value.str() + ".");
#endif
}
// handled
return true;
}
SE_END_CXX
#endif // USE_GNOME_KEYRING

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef INCL_GNOMEPLATFORM
#define INCL_GNOMEPLATFORM
#include <string>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
struct ConfigPasswordKey;
bool GNOMELoadPasswordSlot(const std::string &passwordName,
const std::string &descr,
const ConfigPasswordKey &key,
std::string &password);
bool GNOMESavePasswordSlot(const std::string &passwordName,
const std::string &password,
const ConfigPasswordKey &key);
SE_END_CXX
#endif // INCL_GNOMEPLATFORM

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <config.h>
#ifdef USE_GNOME_KEYRING
#include "GNOMEPlatform.h"
#include <syncevo/SyncConfig.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
static class GNOMEInit
{
public:
GNOMEInit()
{
GetLoadPasswordSignal().connect(1, GNOMELoadPasswordSlot);
GetSavePasswordSignal().connect(1, GNOMESavePasswordSlot);
}
} gnomeinit;
SE_END_CXX
#endif // USE_GNOME_KEYRING

View File

@ -0,0 +1,16 @@
PKG_CHECK_MODULES(KEYRING, [gnome-keyring-1], HAVE_KEYRING=yes, HAVE_KEYRING=no)
AC_ARG_ENABLE(gnome-keyring,
AS_HELP_STRING([--enable-gnome-keyring],
[enables or disables support for the GNOME keyring; default is on if development files are available]),
[enable_gnome_keyring="$enableval"
test "$enable_gnome_keyring" = "yes" || test "$enable_gnome_keyring" = "no" || AC_MSG_ERROR([invalid value for --enable-gnome-keyring: $enable_gnome_keyring])
test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([gnome-keyring-1 pkg not found, needed for --enable-gnome-keyring])],
enable_gnome_keyring="$HAVE_KEYRING")
if test $enable_gnome_keyring = "yes"; then
AC_DEFINE(USE_GNOME_KEYRING, 1, [define if gnome keyring should be used in dbus service])
PKG_CHECK_MODULES([KEYRING_2_20], [gnome-keyring-1 >= 2.20 ],
[AC_DEFINE(GNOME_KEYRING_220, 1, [define if gnome keyring version is above 2.20])],
[true])
# link into static executables, similar to a SyncSource
SYNCSOURCES="$SYNCSOURCES src/backends/gnome/platformgnome.la"
fi

View File

@ -0,0 +1,23 @@
dist_noinst_DATA += src/backends/gnome/configure-sub.in
src_backends_gnome_lib = src/backends/gnome/platformgnome.la
MOSTLYCLEANFILES += $(src_backends_gnome_lib)
src_backends_gnome_platformgnome_la_SOURCES = \
src/backends/gnome/GNOMEPlatform.h \
src/backends/gnome/GNOMEPlatform.cpp
if ENABLE_MODULES
src_backends_gnome_backenddir = $(BACKENDS_DIRECTORY)
src_backends_gnome_backend_LTLIBRARIES = $(src_backends_gnome_lib)
src_backends_gnome_platformgnome_la_SOURCES += \
src/backends/gnome/GNOMEPlatformRegister.cpp
else
noinst_LTLIBRARIES += $(src_backends_gnome_lib)
endif
src_backends_gnome_platformgnome_la_LIBADD = $(KEYRING_LIBS) $(SYNCEVOLUTION_LIBS)
src_backends_gnome_platformgnome_la_LDFLAGS = -module -avoid-version
src_backends_gnome_platformgnome_la_CXXFLAGS = $(KEYRING_CFLAGS) $(SYNCEVOLUTION_CFLAGS)
src_backends_gnome_platformgnome_la_CPPFLAGS = -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
src_backends_gnome_platformgnome_la_DEPENDENCIES = $(SYNCEVOLUTION_LIBS)

View File

@ -0,0 +1,185 @@
/*
* Copyright (C) 2011 Dinesh <saidinesh5@gmail.com>
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <config.h>
#ifdef USE_KDE_KWALLET
#include "KDEPlatform.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QString>
#include <QtCore/QLatin1String>
#include <QtCore/QDebug>
#include <QtDBus/QDBusConnection>
#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#include <kwallet.h>
#include <syncevo/SyncContext.h>
#include <syncevo/SyncConfig.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
void KDEInitMainSlot(const char *appname)
{
//QCoreApplication *app;
int argc = 1;
static char *argv[] = { const_cast<char *>(appname), NULL };
KAboutData aboutData(// The program name used internally.
"syncevolution",
// The message catalog name
// If null, program name is used instead.
0,
// A displayable program name string.
ki18n("SyncEvolution"),
// The program version string.
"1.0",
// Short description of what the app does.
ki18n("Lets Akonadi synchronize with a SyncML Peer"),
// The license this code is released under
KAboutData::License_GPL,
// Copyright Statement
ki18n("(c) 2010-12"),
// Optional text shown in the About box.
// Can contain any information desired.
ki18n(""),
// The program homepage string.
"http://www.syncevolution.org/",
// The bug report email address
"syncevolution@syncevolution.org");
KCmdLineArgs::init(argc, argv, &aboutData);
if (!kapp) {
// Don't allow KApplication to mess with SIGINT/SIGTERM.
// Restore current behavior after construction.
struct sigaction oldsigint, oldsigterm;
sigaction(SIGINT, NULL, &oldsigint);
sigaction(SIGTERM, NULL, &oldsigterm);
// Explicitly disable GUI mode in the KApplication. Otherwise
// the whole binary will fail to run when there is no X11
// display.
new KApplication(false);
//To stop KApplication from spawning it's own DBus Service ... Will have to patch KApplication about this
QDBusConnection::sessionBus().unregisterService("org.syncevolution.syncevolution-"+QString::number(getpid()));
sigaction(SIGINT, &oldsigint, NULL);
sigaction(SIGTERM, &oldsigterm, NULL);
}
}
/**
* Here we use server sync url without protocol prefix and
* user account name as the key in the keyring.
*
* Also since the KWallet's API supports only storing (key,password)
* or Map<QString,QString> , the former is used.
*/
bool KWalletLoadPasswordSlot(const std::string &passwordName,
const std::string &descr,
const ConfigPasswordKey &key,
std::string &password)
{
// When both (presumably) GNOME keyring and KWallet are
// available, check if this is a KDE Session before using
// KWallet instead of GNOME keyring.
if (GetLoadPasswordSignal().num_slots() > 1 &&
!getenv("KDE_FULL_SESSION")) {
return false;
}
QString walletPassword;
QString walletKey = QString(key.user.c_str()) + ',' +
QString(key.domain.c_str())+ ','+
QString(key.server.c_str())+','+
QString(key.object.c_str())+','+
QString(key.protocol.c_str())+','+
QString(key.authtype.c_str())+','+
QString::number(key.port);
QString wallet_name = KWallet::Wallet::NetworkWallet();
//QString folder = QString::fromUtf8("Syncevolution");
const QLatin1String folder("Syncevolution");
password = "";
if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)) {
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous);
if (wallet &&
wallet->setFolder(folder) &&
wallet->readPassword(walletKey, walletPassword) == 0) {
password = walletPassword.toStdString();
return true;
}
}
// not found, ask user
return false;
}
bool KWalletSavePasswordSlot(const std::string &passwordName,
const std::string &password,
const ConfigPasswordKey &key)
{
// see above
if (GetLoadPasswordSignal().num_slots() > 1 &&
!getenv("KDE_FULL_SESSION")) {
return false;
}
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
// write password to keyring
const QString walletKey = QString::fromStdString(key.user + ',' +
key.domain + ',' + key.server + ',' + key.object + ',' +
key.protocol + ',' + key.authtype + ',')+ QString::number(key.port);
const QString walletPassword = QString::fromStdString(password);
bool write_success = false;
const QString wallet_name = KWallet::Wallet::NetworkWallet();
const QLatin1String folder("Syncevolution");
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1,
KWallet::Wallet::Synchronous);
if (wallet) {
if (!wallet->hasFolder(folder)) {
wallet->createFolder(folder);
}
if (wallet->setFolder(folder) &&
wallet->writePassword(walletKey, walletPassword) == 0) {
write_success = true;
}
}
if (!write_success) {
SyncContext::throwError("Saving " + passwordName + " in KWallet failed.");
}
return write_success;
}
SE_END_CXX
#endif // USE_KDE_WALLET

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef INCL_KDEPLATFORM
#define INCL_KDEPLATFORM
#include <string>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
struct ConfigPasswordKey;
void KDEInitMainSlot(const char *appname);
bool KWalletLoadPasswordSlot(const std::string &passwordName,
const std::string &descr,
const ConfigPasswordKey &key,
std::string &password);
bool KWalletSavePasswordSlot(const std::string &passwordName,
const std::string &password,
const ConfigPasswordKey &key);
SE_END_CXX
#endif // INCL_KDEPLATFORM

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2011 Dinesh <saidinesh5@gmail.com>
* Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <config.h>
#ifdef USE_KDE_KWALLET
#include "KDEPlatform.h"
#include <syncevo/SyncContext.h>
#include <syncevo/SyncConfig.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
static class KDEInit
{
public:
KDEInit()
{
GetLoadPasswordSignal().connect(0, KWalletLoadPasswordSlot);
GetSavePasswordSignal().connect(0, KWalletSavePasswordSlot);
SyncContext::GetInitMainSignal().connect(KDEInitMainSlot);
}
} kdeinit;
SE_END_CXX
#endif // USE_KDE_WALLET

View File

@ -0,0 +1,57 @@
# first check for qmake-qt4, because qmake may point to qmake-qt3.
AC_CHECK_PROGS([QMAKE], [qmake-qt4 qmake])
if test "x$QMAKE" != 'x'
then
AC_PATH_PROG([KDE4_CONFIG], [kde4-config], [no])
if test "x$KDE4_CONFIG" != 'xno'
then
KDEKWALLETFOUND=yes
if ! test "$KDE_KWALLET_CFLAGS"; then
KDE_KWALLET_CFLAGS="-I`$KDE4_CONFIG --path include` -I`$KDE4_CONFIG --path include`/KDE `pkg-config --cflags QtDBus QtCore`"
fi
if ! test "$KDE_KWALLET_LIBS"; then
KDE_KWALLET_LIBS="-lkdeui -lkdecore -L`kde4-config --install lib` `pkg-config --libs QtDBus QtCore`"
fi
AC_LANG_PUSH(C++)
old_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $KDE_KWALLET_CFLAGS"
AC_CHECK_HEADERS(kwallet.h, [], [KDEKWALLETFOUND=no])
CPPFLAGS="$old_CPPFLAGS"
AC_LANG_POP(C++)
else
KDEKWALLETFOUND=no
fi
else
KDEKWALLETFOUND=no
fi
# In contrast to the GNOME KEYRING, the KWallet is
# currently considered optional. "configure" will never enable
# by default, because that is a change that might not be
# expected by traditional users.
AC_ARG_ENABLE(kwallet,
AS_HELP_STRING([--enable-kwallet], [enable access to KWallet]),
[use_kde_kwallet="$enableval"
test $KDEKWALLETFOUND = "yes" || test "$use_kde_kwallet" = "no" || AC_MSG_ERROR([kwallet.pc not found. Install it to compile with the KWallet enabled.])],
[use_kde_kwallet="no"])
if test "$use_kde_kwallet" = "yes"; then
# conditional compilation in preprocessor
AC_DEFINE(USE_KDE_KWALLET, 1, [KWallet available])
# link into static executables, similar to a SyncSource
SYNCSOURCES="$SYNCSOURCES src/backends/kde/platformkde.la"
# TODO: KWallet needs Qt. Enable the Qt check in
# configure-post.in, otherwise it fails to compiler
# when none of the backends ask for Qt.
else
# avoid unneeded dependencies on KWallet
KDE_KWALLET_CFLAGS=
KDE_KWALLET_LIBS=
fi
AC_SUBST(KDE_KWALLET_LIBS)
AC_SUBST(KDE_KWALLET_CFLAGS)
# conditional compilation in make
AM_CONDITIONAL([USE_KDE_KWALLET], [test "$use_kde_kwallet" = "yes"])

23
src/backends/kde/kde.am Normal file
View File

@ -0,0 +1,23 @@
dist_noinst_DATA += src/backends/kde/configure-sub.in
src_backends_kde_lib = src/backends/kde/platformkde.la
MOSTLYCLEANFILES += $(src_backends_kde_lib)
src_backends_kde_platformkde_la_SOURCES = \
src/backends/kde/KDEPlatform.h \
src/backends/kde/KDEPlatform.cpp
if ENABLE_MODULES
src_backends_kde_backenddir = $(BACKENDS_DIRECTORY)
src_backends_kde_backend_LTLIBRARIES = $(src_backends_kde_lib)
src_backends_kde_platformkde_la_SOURCES += \
src/backends/kde/KDEPlatformRegister.cpp
else
noinst_LTLIBRARIES += $(src_backends_kde_lib)
endif
src_backends_kde_platformkde_la_LIBADD = $(KDE_KWALLET_LIBS) $(SYNCEVOLUTION_LIBS)
src_backends_kde_platformkde_la_LDFLAGS = -module -avoid-version
src_backends_kde_platformkde_la_CXXFLAGS = $(KDE_KWALLET_CFLAGS) $(SYNCEVOLUTION_CFLAGS)
src_backends_kde_platformkde_la_CPPFLAGS = -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
src_backends_kde_platformkde_la_DEPENDENCIES = $(SYNCEVOLUTION_LIBS)

View File

@ -19,38 +19,10 @@
#include "dbus-user-interface.h"
#ifdef USE_GNOME_KEYRING
extern "C" {
#include <gnome-keyring.h>
}
#endif
// redefining "signals" clashes with the use of that word in gtkbindings.h,
// included via notify.h
#define QT_NO_KEYWORDS
#ifdef USE_KDE_KWALLET
#include <QtCore/QCoreApplication>
#include <QtCore/QString>
#include <QtCore/QLatin1String>
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <QtDBus/QDBusConnection>
#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#include <kwallet.h>
#endif
namespace {
inline const char *passwdStr(const std::string &str)
{
return str.empty() ? NULL : str.c_str();
}
}
SE_BEGIN_CXX
DBusUserInterface::DBusUserInterface(const std::string &config):
@ -63,74 +35,10 @@ string DBusUserInterface::askPassword(const string &passwordName,
const ConfigPasswordKey &key)
{
string password;
#ifdef USE_KDE_KWALLET
/** here we use server sync url without protocol prefix and
* user account name as the key in the keyring */
/* Also since the KWallet's API supports only storing (key,passowrd)
* or Map<QString,QString> , the former is used */
bool isKde=true;
#ifdef USE_GNOME_KEYRING
//When Both GNOME KEYRING and KWALLET are available, Check if this is a KDE Session
//and Call
if(!getenv("KDE_FULL_SESSION"))
isKde=false;
#endif
if (isKde){
QString walletPassword;
QString walletKey = QString(passwdStr(key.user)) + ',' +
QString(passwdStr(key.domain))+ ','+
QString(passwdStr(key.server))+','+
QString(passwdStr(key.object))+','+
QString(passwdStr(key.protocol))+','+
QString(passwdStr(key.authtype))+','+
QString::number(key.port);
QString wallet_name = KWallet::Wallet::NetworkWallet();
//QString folder = QString::fromUtf8("Syncevolution");
const QLatin1String folder("Syncevolution");
if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)){
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous);
if (wallet){
if (wallet->setFolder(folder))
if (wallet->readPassword(walletKey, walletPassword) == 0)
return walletPassword.toStdString();
}
}
}
#endif
#ifdef USE_GNOME_KEYRING
/** here we use server sync url without protocol prefix and
* user account name as the key in the keyring */
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
GnomeKeyringResult result;
GList* list;
result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
&list);
/** if find password stored in gnome keyring */
if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
GnomeKeyringNetworkPasswordData *key_data;
key_data = (GnomeKeyringNetworkPasswordData*)list->data;
password = key_data->password;
gnome_keyring_network_password_list_free(list);
if (GetLoadPasswordSignal()(passwordName, descr, key, password)) {
// handled
return password;
}
#endif
//if not found, return empty
return "";
@ -140,86 +48,11 @@ bool DBusUserInterface::savePassword(const string &passwordName,
const string &password,
const ConfigPasswordKey &key)
{
#ifdef USE_KDE_KWALLET
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
bool isKde=true;
#ifdef USE_GNOME_KEYRING
//When Both GNOME KEYRING and KWALLET are available, Check if this is a KDE Session
//and Call
if(!getenv("KDE_FULL_SESSION"))
isKde=false;
#endif
if(isKde){
// write password to keyring
QString walletKey = QString(passwdStr(key.user)) + ',' +
QString(passwdStr(key.domain))+ ','+
QString(passwdStr(key.server))+','+
QString(passwdStr(key.object))+','+
QString(passwdStr(key.protocol))+','+
QString(passwdStr(key.authtype))+','+
QString::number(key.port);
QString walletPassword = password.c_str();
bool write_success = false;
QString wallet_name = KWallet::Wallet::NetworkWallet();
//QString folder = QString::fromUtf8("Syncevolution");
const QLatin1String folder("Syncevolution");
KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1,
KWallet::Wallet::Synchronous);
if (wallet){
if (!wallet->hasFolder(folder))
wallet->createFolder(folder);
if (wallet->setFolder(folder))
if (wallet->writePassword(walletKey, walletPassword) == 0)
write_success = true;
}
if(!write_success) {
SyncContext::throwError("Try to save " + passwordName + " in kde-wallet but got an error. ");
}
return write_success;
if (GetSavePasswordSignal()(passwordName, password, key)) {
return true;
}
#endif
#ifdef USE_GNOME_KEYRING
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
* but currently only use passed key instead */
guint32 itemId;
GnomeKeyringResult result;
// write password to keyring
result = gnome_keyring_set_network_password_sync(NULL,
passwdStr(key.user),
passwdStr(key.domain),
passwdStr(key.server),
passwdStr(key.object),
passwdStr(key.protocol),
passwdStr(key.authtype),
key.port,
password.c_str(),
&itemId);
/* if set operation is failed */
if(result != GNOME_KEYRING_RESULT_OK) {
#ifdef GNOME_KEYRING_220
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. " + gnome_keyring_result_to_message(result));
#else
/** if gnome-keyring version is below 2.20, it doesn't support 'gnome_keyring_result_to_message'. */
stringstream value;
value << (int)result;
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. The gnome-keyring error code is " + value.str() + ".");
#endif
}
return true;
#else
#endif
/** if no support of gnome-keyring, don't save anything */
// not saved
return false;
}

View File

@ -46,9 +46,9 @@ src_dbus_server_libsyncevodbusserver_la_SOURCES = \
dist_pkgdata_DATA += src/dbus/server/bluetooth_products.ini
src_dbus_server_libsyncevodbusserver_la_LIBADD = $(KEYRING_LIBS) $(LIBNOTIFY_LIBS) $(MLITE_LIBS) $(KDE_KWALLET_LIBS) $(DBUS_LIBS) $(LIBSOUP_LIBS)
src_dbus_server_libsyncevodbusserver_la_LIBADD = $(LIBNOTIFY_LIBS) $(MLITE_LIBS) $(DBUS_LIBS) $(LIBSOUP_LIBS)
src_dbus_server_libsyncevodbusserver_la_CPPFLAGS = -DHAVE_CONFIG_H -DSYNCEVOLUTION_LOCALEDIR=\"${SYNCEVOLUTION_LOCALEDIR}\" -I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir) -I$(gdbus_dir) $(BACKEND_CPPFLAGS)
src_dbus_server_libsyncevodbusserver_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(SYNTHESIS_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS) $(LIBNOTIFY_CFLAGS) $(MLITE_CFLAGS) $(KDE_KWALLET_CFLAGS) $(SYNCEVO_WFLAGS)
src_dbus_server_libsyncevodbusserver_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(SYNTHESIS_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBNOTIFY_CFLAGS) $(MLITE_CFLAGS) $(SYNCEVO_WFLAGS)
# Deal with .service, .desktop and startup script files.
CLEANFILES += \

View File

@ -113,14 +113,14 @@ endif
# SYNCEVOLUTION_LDADD will be replaced with libsyncebook.la/libsyncecal.la/libsyncsqlite.la
# if linking statically against them, empty otherwise;
# either way this does not lead to a dependency on those libs - done explicitly
src_syncevolution_LDADD = $(CORE_LDADD) $(KEYRING_LIBS) $(KDE_KWALLET_LIBS)
src_syncevolution_LDADD = $(CORE_LDADD)
src_syncevolution_DEPENDENCIES = $(EXTRA_LTLIBRARIES) $(CORE_DEP)
if COND_DBUS
src_syncevolution_LDADD += $(gdbus_build_dir)/libgdbussyncevo.la
src_syncevolution_DEPENDENCIES += $(gdbus_build_dir)/libgdbussyncevo.la
endif
src_syncevolution_LDFLAGS = $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(DBUS_LIBS)
src_syncevolution_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(KEYRING_CFLAGS) $(DBUS_CFLAGS) $(KDE_KWALLET_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevolution_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(DBUS_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevolution_CPPFLAGS = $(src_cppflags) -I$(gdbus_dir)
# include Synthesis in distribution: package only files in git if using a git checkout
@ -173,9 +173,9 @@ src_syncevo_local_sync_SOURCES = \
if ENABLE_UNIT_TESTS
nodist_src_syncevo_local_sync_SOURCES = test/test.cpp
endif
src_syncevo_local_sync_LDADD = $(gdbus_build_dir)/libgdbussyncevo.la $(CORE_LDADD) $(KEYRING_LIBS) $(KDE_KWALLET_LIBS) $(DBUS_LIBS)
src_syncevo_local_sync_LDADD = $(gdbus_build_dir)/libgdbussyncevo.la $(CORE_LDADD) $(DBUS_LIBS)
src_syncevo_local_sync_CPPFLAGS = -DHAVE_CONFIG_H -I$(gdbus_dir) $(src_cppflags)
src_syncevo_local_sync_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS) $(KDE_KWALLET_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevo_local_sync_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevo_local_sync_LDFLAGS = $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(LIBSOUP_LIBS)
src_syncevo_local_sync_DEPENDENCIES = $(builddir)/$(gdbus_build_dir)/libgdbussyncevo.la $(EXTRA_LTLIBRARIES) $(CORE_DEP) $(SYNTHESIS_DEP)
@ -191,9 +191,9 @@ if ENABLE_UNIT_TESTS
nodist_src_syncevo_dbus_server_SOURCES = test/test.cpp
endif
src_syncevo_dbus_server_LDADD = $(builddir)/src/dbus/server/libsyncevodbusserver.la $(gdbus_build_dir)/libgdbussyncevo.la $(CORE_LDADD) $(KEYRING_LIBS) $(LIBNOTIFY_LIBS) $(MLITE_LIBS) $(KDE_KWALLET_LIBS) $(DBUS_LIBS)
src_syncevo_dbus_server_LDADD = $(builddir)/src/dbus/server/libsyncevodbusserver.la $(gdbus_build_dir)/libgdbussyncevo.la $(CORE_LDADD) $(LIBNOTIFY_LIBS) $(MLITE_LIBS) $(DBUS_LIBS)
src_syncevo_dbus_server_CPPFLAGS = -DHAVE_CONFIG_H -I$(gdbus_dir) $(src_cppflags) -DSYNCEVOLUTION_LOCALEDIR=\"${SYNCEVOLUTION_LOCALEDIR}\"
src_syncevo_dbus_server_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS) $(LIBNOTIFY_CFLAGS) $(MLITE_CFLAGS) $(KDE_KWALLET_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevo_dbus_server_CXXFLAGS = $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBNOTIFY_CFLAGS) $(MLITE_CFLAGS) $(SYNCEVO_WFLAGS)
src_syncevo_dbus_server_LDFLAGS = $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(LIBSOUP_LIBS)
src_syncevo_dbus_server_DEPENDENCIES = $(builddir)/src/dbus/server/libsyncevodbusserver.la $(gdbus_build_dir)/libgdbussyncevo.la $(EXTRA_LTLIBRARIES) $(CORE_DEP) $(SYNTHESIS_DEP)
endif
@ -254,8 +254,8 @@ TEST_FILES_PATCHED = $(wildcard src/testcases/*.tem)
CLIENT_LIB_TEST_FILES += $(TEST_FILES_GENERATED)
src_client_test_CPPFLAGS = -DHAVE_CONFIG_H -DENABLE_INTEGRATION_TESTS -DENABLE_UNIT_TESTS $(src_cppflags) $(BUTEOSYNCPROFILE_CFLAGS) $(BUTEOSYNCCOMMON_CFLAGS) $(QT_CPPFLAGS)
src_client_test_CXXFLAGS = @CPPUNIT_CXXFLAGS@ $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(KEYRING_CFLAGS) $(BUTEOSYNCPROFILE_CFLAGS) $(BUTEOSYNCCOMMON_CFLAGS) $(filter-out -O2 -g -W -Wall, $(QT_CXXFLAGS)) $(SYNCEVO_WFLAGS)
src_client_test_LDFLAGS = @CPPUNIT_LDFLAGS@ `nm src/syncevo/.libs/libsyncevolution.a | grep funambolAutoRegisterRegistry | sed -e 's/.* /-Wl,-u/'` $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(KEYRING_LIBS) $(KDE_KWALLET_LIBS) $(BUTEOSYNCPROFILE_LIBS) $(BUTEOSYNCCOMMON_LIBS) $(QT_LDFLAGS)
src_client_test_CXXFLAGS = @CPPUNIT_CXXFLAGS@ $(PCRECPP_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(BUTEOSYNCPROFILE_CFLAGS) $(BUTEOSYNCCOMMON_CFLAGS) $(filter-out -O2 -g -W -Wall, $(QT_CXXFLAGS)) $(SYNCEVO_WFLAGS)
src_client_test_LDFLAGS = @CPPUNIT_LDFLAGS@ `nm src/syncevo/.libs/libsyncevolution.a | grep funambolAutoRegisterRegistry | sed -e 's/.* /-Wl,-u/'` $(PCRECPP_LIBS) $(CORE_LD_FLAGS) $(BUTEOSYNCPROFILE_LIBS) $(BUTEOSYNCCOMMON_LIBS) $(QT_LDFLAGS)
src_client_test_LDADD = $(CORE_LDADD) $(SYNTHESIS_ENGINE) $(BUTEOSYNCPROFILE_LIBS) $(BUTEOSYNCCOMMON_LIBS) $(QT_LIBS)
# These dependencies are intentionally a bit too broad:
# they ensure that all files are in place to *run* client-test.

View File

@ -811,13 +811,13 @@ bool Cmdline::run() {
if (m_dryrun) {
SyncContext::throwError("--dry-run not supported for configuration changes");
}
if (m_keyring) {
#if (!defined USE_GNOME_KEYRING) and (!defined USE_KDE_KWALLET)
if (m_keyring &&
GetLoadPasswordSignal().empty()) {
m_err << "Error: this syncevolution binary was compiled without support for storing "
"passwords in a keyring or wallet. Either store passwords in your configuration "
"passwords in a keyring or wallet, or the backends for that functionality are not usable. "
"Either store passwords in your configuration "
"files or enter them interactively on each program run." << endl;
return false;
#endif
}
// name of renamed config ("foo.old") after migration

View File

@ -48,6 +48,19 @@ SE_BEGIN_CXX
const char *const SourceAdminDataName = "adminData";
LoadPasswordSignal &GetLoadPasswordSignal()
{
static LoadPasswordSignal loadPasswordSignal;
return loadPasswordSignal;
}
SavePasswordSignal &GetSavePasswordSignal()
{
static SavePasswordSignal savePasswordSignal;
return savePasswordSignal;
}
int ConfigVersions[CONFIG_LEVEL_MAX][CONFIG_VERSION_MAX] =
{
{ CONFIG_ROOT_MIN_VERSION, CONFIG_ROOT_CUR_VERSION },

View File

@ -28,6 +28,7 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/foreach.hpp>
#include <boost/signals2.hpp>
#include <list>
#include <string>
#include <sstream>
@ -732,6 +733,70 @@ class ConfigUserInterface {
virtual bool savePassword(const std::string &passwordName, const std::string &password, const ConfigPasswordKey &key) = 0;
};
/**
* Some ConfigUserInterface implementations check in the system's
* password manager before asking the user. Backends provide optional
* access to GNOME keyring (maps to freedesktop.org Secrets D-Bus API)
* and KWallet (custom protocol in KDE < 4.8, same Secrets API >=
* 4.8).
*
* The following signals are to be invoked by ConfigUserInterface
* implementations which want to use these extensions. They return
* true if some backend implemented the request, false otherwise.
*/
/**
* call one slot after the other, return as soon as the first one
* returns true
*/
struct TrySlots
{
typedef bool result_type;
template<typename InputIterator>
bool operator()(InputIterator first, InputIterator last) const
{
while (first != last) {
if (*first) {
return true;
}
++first;
}
return false;
}
};
/**
* Same as ConfigUserInterface::askPassword(), except that the
* password is returned in retval and the return value indicates
* whether any slot was able to retrieve the value.
*
* Backends need to be sure that the user wants them to handle
* the request before doing the work and returning true.
*
* GNOME keyring and KWallet add themselves here and in
* SavePasswordSignal. KWallet adds itself with priority 0
* and GNOME keyring with 1, which means that KWallet is called
* first. It checks whether KDE really is the preferred
* storage, otherwise defers to GNOME keyring (or any other
* slot) by returning false.
*/
typedef boost::signals2::signal<bool (const std::string &passwordName,
const std::string &descr,
const ConfigPasswordKey &key,
std::string &password),
TrySlots> LoadPasswordSignal;
LoadPasswordSignal &GetLoadPasswordSignal();
/**
* Same as AskPasswordSignal for saving.
*/
typedef boost::signals2::signal<bool (const std::string &passwordName,
const std::string &password,
const ConfigPasswordKey &key),
TrySlots> SavePasswordSignal;
SavePasswordSignal &GetSavePasswordSignal();
class PasswordConfigProperty : public ConfigProperty {
public:
PasswordConfigProperty(const std::string &name, const std::string &comment, const std::string &def = std::string(""),const std::string &descr = std::string("")) :

View File

@ -71,18 +71,6 @@ using namespace std;
#include <synthesis/SDK_util.h>
#include <synthesis/san.h>
#ifdef USE_KDE_KWALLET
#include <QtCore/QCoreApplication>
#include <QtCore/QString>
#include <QtCore/QLatin1String>
#include <QtCore/QDebug>
#include <QtDBus/QDBusConnection>
#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>
#endif
#include "test.h"
#include <syncevo/declarations.h>
@ -2835,52 +2823,9 @@ void SyncContext::initMain(const char *appname)
g_log_set_default_handler(Logger::glogFunc, NULL);
#endif
#ifdef USE_KDE_KWALLET
//QCoreApplication *app;
int argc = 1;
static char *argv[] = { const_cast<char *>(appname), NULL };
KAboutData aboutData(// The program name used internally.
"syncevolution",
// The message catalog name
// If null, program name is used instead.
0,
// A displayable program name string.
ki18n("SyncEvolution"),
// The program version string.
"1.0",
// Short description of what the app does.
ki18n("Lets Akonadi synchronize with a SyncML Peer"),
// The license this code is released under
KAboutData::License_GPL,
// Copyright Statement
ki18n("(c) 2010-12"),
// Optional text shown in the About box.
// Can contain any information desired.
ki18n(""),
// The program homepage string.
"http://www.syncevolution.org/",
// The bug report email address
"syncevolution@syncevolution.org");
KCmdLineArgs::init(argc, argv, &aboutData);
if (!kapp) {
// Don't allow KApplication to mess with SIGINT/SIGTERM.
// Restore current behavior after construction.
struct sigaction oldsigint, oldsigterm;
sigaction(SIGINT, NULL, &oldsigint);
sigaction(SIGTERM, NULL, &oldsigterm);
// Explicitly disable GUI mode in the KApplication. Otherwise
// the whole binary will fail to run when there is no X11
// display.
new KApplication(false);
//To stop KApplication from spawning it's own DBus Service ... Will have to patch KApplication about this
QDBusConnection::sessionBus().unregisterService("org.syncevolution.syncevolution-"+QString::number(getpid()));
sigaction(SIGINT, &oldsigint, NULL);
sigaction(SIGTERM, &oldsigterm, NULL);
}
#endif
// invoke optional init parts, for example KDE KApplication init
// in KDE backend
GetInitMainSignal()(appname);
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
@ -2914,6 +2859,12 @@ void SyncContext::initMain(const char *appname)
}
}
SyncContext::InitMainSignal &SyncContext::GetInitMainSignal()
{
static InitMainSignal initMainSignal;
return initMainSignal;
}
static bool IsStableRelease =
#ifdef SYNCEVOLUTION_STABLE_RELEASE
true

View File

@ -32,6 +32,7 @@
#include <stdint.h>
#include <boost/smart_ptr.hpp>
#include <boost/signals2.hpp>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
@ -148,6 +149,13 @@ class SyncContext : public SyncConfig, public ConfigUserInterface {
*/
static void initMain(const char *appname);
/**
* A signal invoked as part of initMain().
* Backends can connect to it to extend initMain().
*/
typedef boost::signals2::signal<void (const char *appname)> InitMainSignal;
static InitMainSignal &GetInitMainSignal();
/**
* true if binary was compiled as stable release
* (see gen-autotools.sh)

View File

@ -182,7 +182,6 @@ src_syncevo_libsyncevolution_la_LIBADD = \
@GIO_LIBS@ \
@GTHREAD_LIBS@ \
@GLIB_LIBS@ \
$(KDE_KWALLET_LIBS) \
$(SYNTHESIS_LIBS) \
$(PCRECPP_LIBS) \
$(TRANSPORT_LIBS) \

View File

@ -771,8 +771,10 @@
# ==7816== by 0x5344EB: SyncEvo::Server::run(SyncEvo::LogRedirect&) (server.cpp:344)
# ==7816== by 0x515CE3: main (main.cpp:117)
# ==7816==
#
# Different backtrace starting with the move of GNOME keyring support into a backend.
{
gcrypt + GNOME keyring
gcrypt + GNOME keyring + modules
Memcheck:Leak
fun:malloc
fun:g_malloc
@ -780,7 +782,7 @@
...
obj:*libgnome-keyring.so*
...
fun:*DBusUserInterface*Password*
fun:*GNOME*Password*
}
# ==10804== 60 (16 direct, 44 indirect) bytes in 1 blocks are definitely lost in loss record 1,121 of 2,014
@ -930,8 +932,7 @@
KApplication + malloc
Memcheck:Leak
...
fun:*KApplication*
fun:*SyncContext*initMain*
fun:*KDEInitMain*
}
{
Qt + malloc