File: | syncevolution/src/backends/kde/KDEPlatform.cpp |
Warning: | line 110, column 9 Potential memory leak |
1 | /* | |||
2 | * Copyright (C) 2011 Dinesh <saidinesh5@gmail.com> | |||
3 | * Copyright (C) 2012 Intel Corporation | |||
4 | * | |||
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. | |||
9 | * | |||
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. | |||
14 | * | |||
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 | |||
18 | * 02110-1301 USA | |||
19 | */ | |||
20 | ||||
21 | #include <config.h> | |||
22 | ||||
23 | #ifdef USE_KDE_KWALLET1 | |||
24 | ||||
25 | #include "KDEPlatform.h" | |||
26 | ||||
27 | #include <syncevo/Exception.h> | |||
28 | #include <syncevo/UserInterface.h> | |||
29 | #include <syncevo/SyncConfig.h> | |||
30 | ||||
31 | // Qt headers may define "signals" as preprocessor symbol, | |||
32 | // which conflicts with glib C headers included indirectly | |||
33 | // above. This order of header files works. | |||
34 | #include <QtCore/QCoreApplication> | |||
35 | #include <QtCore/QString> | |||
36 | #include <QtCore/QLatin1String> | |||
37 | #include <QtCore/QDebug> | |||
38 | #include <QtDBus/QDBusConnection> | |||
39 | ||||
40 | #include <KApplication> | |||
41 | #include <KAboutData> | |||
42 | #include <KCmdLineArgs> | |||
43 | ||||
44 | #include <kwallet.h> | |||
45 | ||||
46 | #include <syncevo/declarations.h> | |||
47 | SE_BEGIN_CXXnamespace SyncEvo { | |||
48 | ||||
49 | // TODO: this check should be global | |||
50 | static bool HaveDBus; | |||
51 | ||||
52 | void KDEInitMainSlot(const char *appname) | |||
53 | { | |||
54 | // Very simple check. API doesn't say whether asking | |||
55 | // for the bus connection will connect immediately. | |||
56 | // We use a private connection here instead of the shared | |||
57 | // QDBusConnection::sessionBus() because we don't have | |||
58 | // a QCoreApplication yet. Otherwise we get a warning: | |||
59 | // "QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave." | |||
60 | { | |||
61 | QDBusConnection dbus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "org.syncevolution.kde-platform-test-connection"); | |||
62 | HaveDBus = dbus.isConnected(); | |||
63 | } | |||
64 | ||||
65 | if (!HaveDBus) { | |||
| ||||
66 | // KApplication has been seen to crash without D-Bus (BMC #25596). | |||
67 | // Bail out here if we don't have D-Bus. | |||
68 | return; | |||
69 | } | |||
70 | ||||
71 | //QCoreApplication *app; | |||
72 | int argc = 1; | |||
73 | static char *argv[] = { const_cast<char *>(appname), NULL__null }; | |||
74 | KAboutData aboutData(// The program name used internally. | |||
75 | "syncevolution", | |||
76 | // The message catalog name | |||
77 | // If null, program name is used instead. | |||
78 | 0, | |||
79 | // A displayable program name string. | |||
80 | ki18n("SyncEvolution"), | |||
81 | // The program version string. | |||
82 | VERSION"1.5.3", | |||
83 | // Short description of what the app does. | |||
84 | ki18n("Lets Akonadi synchronize with a SyncML Peer"), | |||
85 | // The license this code is released under | |||
86 | KAboutData::License_GPL, | |||
87 | // Copyright Statement | |||
88 | ki18n("(c) 2010-12"), | |||
89 | // Optional text shown in the About box. | |||
90 | // Can contain any information desired. | |||
91 | ki18n(""), | |||
92 | // The program homepage string. | |||
93 | "http://www.syncevolution.org/", | |||
94 | // The bug report email address | |||
95 | "syncevolution@syncevolution.org"); | |||
96 | ||||
97 | KCmdLineArgs::init(argc, argv, &aboutData); | |||
98 | if (!kappKApplication::kApplication()) { | |||
99 | // Don't allow KApplication to mess with SIGINT/SIGTERM. | |||
100 | // Restore current behavior after construction. | |||
101 | struct sigaction oldsigint, oldsigterm; | |||
102 | sigaction(SIGINT2, NULL__null, &oldsigint); | |||
103 | sigaction(SIGTERM15, NULL__null, &oldsigterm); | |||
104 | ||||
105 | // Explicitly disable GUI mode in the KApplication. Otherwise | |||
106 | // the whole binary will fail to run when there is no X11 | |||
107 | // display. | |||
108 | new KApplication(false); | |||
109 | //To stop KApplication from spawning it's own DBus Service ... Will have to patch KApplication about this | |||
110 | QDBusConnection::sessionBus().unregisterService("org.syncevolution.syncevolution-"+QString::number(getpid())); | |||
| ||||
111 | ||||
112 | sigaction(SIGINT2, &oldsigint, NULL__null); | |||
113 | sigaction(SIGTERM15, &oldsigterm, NULL__null); | |||
114 | } | |||
115 | } | |||
116 | ||||
117 | static bool UseKWallet(const InitStateTri &keyring, | |||
118 | int slotCount) | |||
119 | { | |||
120 | // Disabled by user? | |||
121 | if (keyring.getValue() == InitStateTri::VALUE_FALSE) { | |||
122 | return false; | |||
123 | } | |||
124 | ||||
125 | // When both (presumably) GNOME keyring and KWallet are available, | |||
126 | // check if the user really wanted KWallet before using KWallet | |||
127 | // instead of GNOME keyring. This default favors GNOME keyring | |||
128 | // over KWallet because SyncEvolution traditionally used that. | |||
129 | if (keyring.getValue() == InitStateTri::VALUE_TRUE && | |||
130 | slotCount > 1) { | |||
131 | return false; | |||
132 | } | |||
133 | ||||
134 | // If explicitly selected, it must be us. | |||
135 | if (keyring.getValue() == InitStateTri::VALUE_STRING && | |||
136 | !boost::iequals(keyring.get(), "KDE")) { | |||
137 | return false; | |||
138 | } | |||
139 | ||||
140 | // User wants KWallet, but is it usable? | |||
141 | if (!HaveDBus) { | |||
142 | SE_THROW("KDE KWallet requested, but it is not usable (running outside of a D-Bus session)")throw Exception("/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 142, "KDE KWallet requested, but it is not usable (running outside of a D-Bus session)" ); | |||
143 | } | |||
144 | ||||
145 | // Use KWallet. | |||
146 | return true; | |||
147 | } | |||
148 | ||||
149 | /** | |||
150 | * Here we use server sync url without protocol prefix and | |||
151 | * user account name as the key in the keyring. | |||
152 | * | |||
153 | * Also since the KWallet's API supports only storing (key,password) | |||
154 | * or Map<QString,QString> , the former is used. | |||
155 | */ | |||
156 | bool KWalletLoadPasswordSlot(const InitStateTri &keyring, | |||
157 | const std::string &passwordName, | |||
158 | const std::string &descr, | |||
159 | const ConfigPasswordKey &key, | |||
160 | InitStateString &password) | |||
161 | { | |||
162 | if (!UseKWallet(keyring, | |||
163 | GetLoadPasswordSignal().num_slots() - INTERNAL_LOAD_PASSWORD_SLOTS)) { | |||
164 | SE_LOG_DEBUG(NULL, "not using KWallet")SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 164, __null, "not using KWallet");; | |||
165 | return false; | |||
166 | } | |||
167 | ||||
168 | QString walletPassword; | |||
169 | QString walletKey = QString(key.user.c_str()) + ',' + | |||
170 | QString(key.domain.c_str())+ ','+ | |||
171 | QString(key.server.c_str())+','+ | |||
172 | QString(key.object.c_str())+','+ | |||
173 | QString(key.protocol.c_str())+','+ | |||
174 | QString(key.authtype.c_str())+','+ | |||
175 | QString::number(key.port); | |||
176 | ||||
177 | QString wallet_name = KWallet::Wallet::NetworkWallet(); | |||
178 | //QString folder = QString::fromUtf8("Syncevolution"); | |||
179 | const QLatin1String folder("Syncevolution"); | |||
180 | ||||
181 | bool found = false; | |||
182 | if (!KWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)) { | |||
183 | KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, KWallet::Wallet::Synchronous); | |||
184 | if (wallet && | |||
185 | wallet->setFolder(folder) && | |||
186 | wallet->readPassword(walletKey, walletPassword) == 0) { | |||
187 | password = walletPassword.toStdString(); | |||
188 | found = true; | |||
189 | } | |||
190 | } | |||
191 | SE_LOG_DEBUG(NULL, "%s password in KWallet using %s",SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 193, __null, "%s password in KWallet using %s", found ? "found" : "no", key.toString().c_str()); | |||
192 | found ? "found" : "no",SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 193, __null, "%s password in KWallet using %s", found ? "found" : "no", key.toString().c_str()); | |||
193 | key.toString().c_str())SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 193, __null, "%s password in KWallet using %s", found ? "found" : "no", key.toString().c_str());; | |||
194 | ||||
195 | return true; | |||
196 | } | |||
197 | ||||
198 | ||||
199 | bool KWalletSavePasswordSlot(const InitStateTri &keyring, | |||
200 | const std::string &passwordName, | |||
201 | const std::string &password, | |||
202 | const ConfigPasswordKey &key) | |||
203 | { | |||
204 | if (!UseKWallet(keyring, | |||
205 | GetSavePasswordSignal().num_slots() - INTERNAL_SAVE_PASSWORD_SLOTS)) { | |||
206 | SE_LOG_DEBUG(NULL, "not using KWallet")SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 206, __null, "not using KWallet");; | |||
207 | return false; | |||
208 | } | |||
209 | ||||
210 | /* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use | |||
211 | * but currently only use passed key instead */ | |||
212 | ||||
213 | // write password to keyring | |||
214 | const QString walletKey = QString::fromStdString(key.user + ',' + | |||
215 | key.domain + ',' + key.server + ',' + key.object + ',' + | |||
216 | key.protocol + ',' + key.authtype + ',')+ QString::number(key.port); | |||
217 | const QString walletPassword = QString::fromStdString(password); | |||
218 | ||||
219 | bool write_success = false; | |||
220 | const QString wallet_name = KWallet::Wallet::NetworkWallet(); | |||
221 | const QLatin1String folder("Syncevolution"); | |||
222 | KWallet::Wallet *wallet = KWallet::Wallet::openWallet(wallet_name, -1, | |||
223 | KWallet::Wallet::Synchronous); | |||
224 | if (wallet) { | |||
225 | if (!wallet->hasFolder(folder)) { | |||
226 | wallet->createFolder(folder); | |||
227 | } | |||
228 | ||||
229 | if (wallet->setFolder(folder) && | |||
230 | wallet->writePassword(walletKey, walletPassword) == 0) { | |||
231 | write_success = true; | |||
232 | } | |||
233 | } | |||
234 | ||||
235 | if (!write_success) { | |||
236 | Exception::throwError(SE_HERESyncEvo::SourceLocation("/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 236), "Saving " + passwordName + " in KWallet failed."); | |||
237 | } | |||
238 | SE_LOG_DEBUG(NULL, "stored password in KWallet using %s",SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 239, __null, "stored password in KWallet using %s", key.toString ().c_str()); | |||
239 | key.toString().c_str())SyncEvo::Logger::instance().message(SyncEvo::Logger::DEBUG, __null , "/data/runtests/work/sources/syncevolution/src/backends/kde/KDEPlatform.cpp" , 239, __null, "stored password in KWallet using %s", key.toString ().c_str());; | |||
240 | return write_success; | |||
241 | } | |||
242 | ||||
243 | SE_END_CXX} | |||
244 | ||||
245 | #endif // USE_KDE_WALLET |