Bug Summary

File:syncevolution/src/backends/kde/KDEPlatform.cpp
Warning:line 110, column 9
Potential memory leak

Annotated Source Code

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>
47SE_BEGIN_CXXnamespace SyncEvo {
48
49// TODO: this check should be global
50static bool HaveDBus;
51
52void 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) {
1
Assuming 'HaveDBus' is not equal to 0
2
Taking false branch
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()) {
3
Assuming the condition is true
4
Taking true branch
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);
5
Memory is allocated
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()));
6
Potential memory leak
111
112 sigaction(SIGINT2, &oldsigint, NULL__null);
113 sigaction(SIGTERM15, &oldsigterm, NULL__null);
114 }
115}
116
117static 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 */
156bool 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
199bool 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
243SE_END_CXX}
244
245#endif // USE_KDE_WALLET