2 * Copyright (C) 2011 Dinesh <saidinesh5@gmail.com>
3 * Copyright (C) 2012 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #ifdef USE_KDE_KWALLET
25 #include "KDEPlatform.h"
27 #include <syncevo/SyncContext.h>
28 #include <syncevo/SyncConfig.h>
30 // Qt headers may define "signals" as preprocessor symbol,
31 // which conflicts with glib C headers included indirectly
32 // above. This order of header files works.
33 #include <QtCore/QCoreApplication>
34 #include <QtCore/QString>
35 #include <QtCore/QLatin1String>
36 #include <QtCore/QDebug>
37 #include <QtDBus/QDBusConnection>
39 #include <KApplication>
41 #include <KCmdLineArgs>
45 #include <syncevo/declarations.h>
48 // TODO: this check should be global
51 void KDEInitMainSlot(const char *appname)
53 // Very simple check. API doesn't say whether asking
54 // for the bus connection will connect immediately.
55 QDBusConnection dbus = QDBusConnection::sessionBus();
56 HaveDBus = dbus.isConnected();
59 // KApplication has been seen to crash without D-Bus (BMC #25596).
60 // Bail out here if we don't have D-Bus.
64 //QCoreApplication *app;
66 static char *argv[] = { const_cast<char *>(appname), NULL };
67 KAboutData aboutData(// The program name used internally.
69 // The message catalog name
70 // If null, program name is used instead.
72 // A displayable program name string.
73 ki18n("SyncEvolution"),
74 // The program version string.
76 // Short description of what the app does.
77 ki18n("Lets Akonadi synchronize with a SyncML Peer"),
78 // The license this code is released under
79 KAboutData::License_GPL,
80 // Copyright Statement
82 // Optional text shown in the About box.
83 // Can contain any information desired.
85 // The program homepage string.
86 "http://www.syncevolution.org/",
87 // The bug report email address
88 "syncevolution@syncevolution.org");
90 KCmdLineArgs::init(argc, argv, &aboutData);
92 // Don't allow KApplication to mess with SIGINT/SIGTERM.
93 // Restore current behavior after construction.
94 struct sigaction oldsigint, oldsigterm;
95 sigaction(SIGINT, NULL, &oldsigint);
96 sigaction(SIGTERM, NULL, &oldsigterm);
98 // Explicitly disable GUI mode in the KApplication. Otherwise
99 // the whole binary will fail to run when there is no X11
101 new KApplication(false);
102 //To stop KApplication from spawning it's own DBus Service ... Will have to patch KApplication about this
103 QDBusConnection::sessionBus().unregisterService("org.syncevolution.syncevolution-"+QString::number(getpid()));
105 sigaction(SIGINT, &oldsigint, NULL);
106 sigaction(SIGTERM, &oldsigterm, NULL);
110 static bool UseKWallet(const InitStateTri &keyring,
114 if (keyring.getValue() == InitStateTri::VALUE_FALSE) {
118 // When both (presumably) GNOME keyring and KWallet are available,
119 // check if the user really wanted KWallet before using KWallet
120 // instead of GNOME keyring. This default favors GNOME keyring
121 // over KWallet because SyncEvolution traditionally used that.
122 if (keyring.getValue() == InitStateTri::VALUE_TRUE &&
127 // If explicitly selected, it must be us.
128 if (keyring.getValue() == InitStateTri::VALUE_STRING &&
129 !boost::iequals(keyring.get(), "KDE")) {
133 // User wants KWallet, but is it usable?
135 SE_THROW("KDE KWallet requested, but it is not usable (running outside of a D-Bus session)");
143 * Here we use server sync url without protocol prefix and
144 * user account name as the key in the keyring.
146 * Also since the KWallet's API supports only storing (key,password)
147 * or Map<QString,QString> , the former is used.
149 bool KWalletLoadPasswordSlot(const InitStateTri &keyring,
150 const std::string &passwordName,
151 const std::string &descr,
152 const ConfigPasswordKey &key,
153 InitStateString &password)
155 if (!UseKWallet(keyring,
156 GetLoadPasswordSignal().num_slots() - INTERNAL_LOAD_PASSWORD_SLOTS)) {
160 QString walletPassword;
161 QString walletKey = QString(key.user.c_str()) + ',' +
162 QString(key.domain.c_str())+ ','+
163 QString(key.server.c_str())+','+
164 QString(key.object.c_str())+','+
165 QString(key.protocol.c_str())+','+
166 QString(key.authtype.c_str())+','+
167 QString::number(key.port);
169 QString wallet_name = KWallet::Wallet::NetworkWallet();
170 //QString folder = QString::fromUtf8("Syncevolution");
171 const QLatin1String folder("Syncevolution");
173 if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)) {
174 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous);
176 wallet->setFolder(folder) &&
177 wallet->readPassword(walletKey, walletPassword) == 0) {
178 password = walletPassword.toStdString();
186 bool KWalletSavePasswordSlot(const InitStateTri &keyring,
187 const std::string &passwordName,
188 const std::string &password,
189 const ConfigPasswordKey &key)
191 if (!UseKWallet(keyring,
192 GetSavePasswordSignal().num_slots() - INTERNAL_SAVE_PASSWORD_SLOTS)) {
196 /* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
197 * but currently only use passed key instead */
199 // write password to keyring
200 const QString walletKey = QString::fromStdString(key.user + ',' +
201 key.domain + ',' + key.server + ',' + key.object + ',' +
202 key.protocol + ',' + key.authtype + ',')+ QString::number(key.port);
203 const QString walletPassword = QString::fromStdString(password);
205 bool write_success = false;
206 const QString wallet_name = KWallet::Wallet::NetworkWallet();
207 const QLatin1String folder("Syncevolution");
208 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1,
209 KWallet::Wallet::Synchronous);
211 if (!wallet->hasFolder(folder)) {
212 wallet->createFolder(folder);
215 if (wallet->setFolder(folder) &&
216 wallet->writePassword(walletKey, walletPassword) == 0) {
217 write_success = true;
221 if (!write_success) {
222 SyncContext::throwError("Saving " + passwordName + " in KWallet failed.");
224 return write_success;
229 #endif // USE_KDE_WALLET