summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2005-06-24 23:41:53 (UTC)
committer zautrix <zautrix>2005-06-24 23:41:53 (UTC)
commit6a5f5375a9d2370db7d774b31d299acc81a77f89 (patch) (unidiff)
tree536ac03a132b166596cde3c3a99caa440a3fd609
parent184833db0d1bcb63e7d4bd5945ccdc0e6b92f7b8 (diff)
downloadkdepimpi-6a5f5375a9d2370db7d774b31d299acc81a77f89.zip
kdepimpi-6a5f5375a9d2370db7d774b31d299acc81a77f89.tar.gz
kdepimpi-6a5f5375a9d2370db7d774b31d299acc81a77f89.tar.bz2
fixxxx
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 36b0df5..1f3c58b 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,1207 +1,1207 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager 14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
18 **************************************************************************/ 18 **************************************************************************/
19 19
20#include "pwmdoc.h" 20#include "pwmdoc.h"
21#include "pwmview.h" 21#include "pwmview.h"
22#include "blowfish.h" 22#include "blowfish.h"
23#include "sha1.h" 23#include "sha1.h"
24#include "globalstuff.h" 24#include "globalstuff.h"
25#include "gpasmanfile.h" 25#include "gpasmanfile.h"
26#include "serializer.h" 26#include "serializer.h"
27#include "compressgzip.h" 27#include "compressgzip.h"
28//US#include "compressbzip2.h" 28//US#include "compressbzip2.h"
29#include "randomizer.h" 29#include "randomizer.h"
30#include "pwminit.h" 30#include "pwminit.h"
31#include "libgcryptif.h" 31#include "libgcryptif.h"
32#ifdef PWM_EMBEDDED 32#ifdef PWM_EMBEDDED
33#include "pwmprefs.h" 33#include "pwmprefs.h"
34#include "kglobal.h" 34#include "kglobal.h"
35#endif 35#endif
36 36
37#include <kmessagebox.h> 37#include <kmessagebox.h>
38#include <kconfig.h> 38#include <kconfig.h>
39#include <kglobalsettings.h> 39#include <kglobalsettings.h>
40#include <libkcal/syncdefines.h> 40#include <libkcal/syncdefines.h>
41 41
42 42
43#ifdef CONFIG_KWALLETIF 43#ifdef CONFIG_KWALLETIF
44# include "kwalletemu.h" 44# include "kwalletemu.h"
45#endif // CONFIG_KWALLETIF 45#endif // CONFIG_KWALLETIF
46 46
47#include <qdatetime.h> 47#include <qdatetime.h>
48#include <qsize.h> 48#include <qsize.h>
49#include <qfileinfo.h> 49#include <qfileinfo.h>
50#include <qfile.h> 50#include <qfile.h>
51 51
52#include <stdio.h> 52#include <stdio.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <errno.h> 54#include <errno.h>
55#include <string.h> 55#include <string.h>
56//US#include <iostream> 56//US#include <iostream>
57#include <algorithm> 57#include <algorithm>
58#include <sys/types.h> 58#include <sys/types.h>
59#include <sys/stat.h> 59#include <sys/stat.h>
60#ifndef _WIN32_ 60#ifndef _WIN32_
61#include <unistd.h> 61#include <unistd.h>
62#include <stdint.h> 62#include <stdint.h>
63#endif 63#endif
64 64
65#ifdef PWM_EMBEDDED 65#ifdef PWM_EMBEDDED
66#ifndef Q_LONG 66#ifndef Q_LONG
67#define Q_LONG long 67#define Q_LONG long
68#endif 68#endif
69 69
70#ifndef Q_ULONG 70#ifndef Q_ULONG
71#define Q_ULONG unsigned long 71#define Q_ULONG unsigned long
72#endif 72#endif
73#endif //PWM_EMBEDDED 73#endif //PWM_EMBEDDED
74 74
75 75
76//TODO: reset to its normal value. 76//TODO: reset to its normal value.
77//LR set to 5 min 77//LR set to 5 min
78 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */ 78 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */
79 79
80using namespace std; 80using namespace std;
81 81
82 82
83void PwMDocList::add(PwMDoc *doc, const string &id) 83void PwMDocList::add(PwMDoc *doc, const string &id)
84{ 84{
85#ifdef PWM_DEBUG 85#ifdef PWM_DEBUG
86 // check for existance of object in debug mode only. 86 // check for existance of object in debug mode only.
87 vector<listItem>::iterator begin = docList.begin(), 87 vector<listItem>::iterator begin = docList.begin(),
88 end = docList.end(), 88 end = docList.end(),
89 i = begin; 89 i = begin;
90 while (i != end) { 90 while (i != end) {
91 if (i->doc == doc) { 91 if (i->doc == doc) {
92 BUG(); 92 BUG();
93 return; 93 return;
94 } 94 }
95 ++i; 95 ++i;
96 } 96 }
97#endif 97#endif
98 listItem newItem; 98 listItem newItem;
99 newItem.doc = doc; 99 newItem.doc = doc;
100 newItem.docId = id; 100 newItem.docId = id;
101 docList.push_back(newItem); 101 docList.push_back(newItem);
102} 102}
103 103
104void PwMDocList::edit(PwMDoc *doc, const string &newId) 104void PwMDocList::edit(PwMDoc *doc, const string &newId)
105{ 105{
106 vector<listItem>::iterator begin = docList.begin(), 106 vector<listItem>::iterator begin = docList.begin(),
107 end = docList.end(), 107 end = docList.end(),
108 i = begin; 108 i = begin;
109 while (i != end) { 109 while (i != end) {
110 if (i->doc == doc) { 110 if (i->doc == doc) {
111 i->docId = newId; 111 i->docId = newId;
112 return; 112 return;
113 } 113 }
114 ++i; 114 ++i;
115 } 115 }
116} 116}
117 117
118void PwMDocList::del(PwMDoc *doc) 118void PwMDocList::del(PwMDoc *doc)
119{ 119{
120 vector<listItem>::iterator begin = docList.begin(), 120 vector<listItem>::iterator begin = docList.begin(),
121 end = docList.end(), 121 end = docList.end(),
122 i = begin; 122 i = begin;
123 while (i != end) { 123 while (i != end) {
124 if (i->doc == doc) { 124 if (i->doc == doc) {
125 docList.erase(i); 125 docList.erase(i);
126 return; 126 return;
127 } 127 }
128 ++i; 128 ++i;
129 } 129 }
130} 130}
131 131
132bool PwMDocList::find(const string &id, listItem *ret) 132bool PwMDocList::find(const string &id, listItem *ret)
133{ 133{
134 vector<listItem>::iterator begin = docList.begin(), 134 vector<listItem>::iterator begin = docList.begin(),
135 end = docList.end(), 135 end = docList.end(),
136 i = begin; 136 i = begin;
137 while (i != end) { 137 while (i != end) {
138 if (i->docId == id) { 138 if (i->docId == id) {
139 if (ret) 139 if (ret)
140 *ret = *i; 140 *ret = *i;
141 return true; 141 return true;
142 } 142 }
143 ++i; 143 ++i;
144 } 144 }
145 return false; 145 return false;
146} 146}
147 147
148 148
149 149
150DocTimer::DocTimer(PwMDoc *_doc) 150DocTimer::DocTimer(PwMDoc *_doc)
151 : doc (_doc) 151 : doc (_doc)
152 , mpwLock (0) 152 , mpwLock (0)
153 , autoLockLock (0) 153 , autoLockLock (0)
154 , metaCheckLock (0) 154 , metaCheckLock (0)
155{ 155{
156 mpwTimer = new QTimer; 156 mpwTimer = new QTimer;
157 autoLockTimer = new QTimer; 157 autoLockTimer = new QTimer;
158 metaCheckTimer = new QTimer; 158 metaCheckTimer = new QTimer;
159 connect(mpwTimer, SIGNAL(timeout()), 159 connect(mpwTimer, SIGNAL(timeout()),
160 this, SLOT(mpwTimeout())); 160 this, SLOT(mpwTimeout()));
161 connect(autoLockTimer, SIGNAL(timeout()), 161 connect(autoLockTimer, SIGNAL(timeout()),
162 this, SLOT(autoLockTimeout())); 162 this, SLOT(autoLockTimeout()));
163 connect(metaCheckTimer, SIGNAL(timeout()), 163 connect(metaCheckTimer, SIGNAL(timeout()),
164 this, SLOT(metaCheckTimeout())); 164 this, SLOT(metaCheckTimeout()));
165} 165}
166 166
167DocTimer::~DocTimer() 167DocTimer::~DocTimer()
168{ 168{
169 delete mpwTimer; 169 delete mpwTimer;
170 delete autoLockTimer; 170 delete autoLockTimer;
171 delete metaCheckTimer; 171 delete metaCheckTimer;
172} 172}
173 173
174void DocTimer::start(TimerIDs timer) 174void DocTimer::start(TimerIDs timer)
175{ 175{
176 switch (timer) { 176 switch (timer) {
177 case id_mpwTimer: 177 case id_mpwTimer:
178 if (mpwTimer->isActive()) 178 if (mpwTimer->isActive())
179 mpwTimer->stop(); 179 mpwTimer->stop();
180 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 180 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
181 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); 181 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
182 break; 182 break;
183 case id_autoLockTimer: 183 case id_autoLockTimer:
184 if (autoLockTimer->isActive()) 184 if (autoLockTimer->isActive())
185 autoLockTimer->stop(); 185 autoLockTimer->stop();
186 if (conf()->confGlobLockTimeout() > 0) 186 if (conf()->confGlobLockTimeout() > 0)
187 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); 187 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
188 break; 188 break;
189 case id_metaCheckTimer: 189 case id_metaCheckTimer:
190 if (metaCheckTimer->isActive()) 190 if (metaCheckTimer->isActive())
191 metaCheckTimer->stop(); 191 metaCheckTimer->stop();
192 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 192 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
193 break; 193 break;
194 } 194 }
195} 195}
196 196
197void DocTimer::stop(TimerIDs timer) 197void DocTimer::stop(TimerIDs timer)
198{ 198{
199 switch (timer) { 199 switch (timer) {
200 case id_mpwTimer: 200 case id_mpwTimer:
201 mpwTimer->stop(); 201 mpwTimer->stop();
202 break; 202 break;
203 case id_autoLockTimer: 203 case id_autoLockTimer:
204 autoLockTimer->stop(); 204 autoLockTimer->stop();
205 break; 205 break;
206 case id_metaCheckTimer: 206 case id_metaCheckTimer:
207 metaCheckTimer->stop(); 207 metaCheckTimer->stop();
208 break; 208 break;
209 } 209 }
210} 210}
211 211
212void DocTimer::getLock(TimerIDs timer) 212void DocTimer::getLock(TimerIDs timer)
213{ 213{
214 switch (timer) { 214 switch (timer) {
215 case id_mpwTimer: 215 case id_mpwTimer:
216 ++mpwLock; 216 ++mpwLock;
217 break; 217 break;
218 case id_autoLockTimer: 218 case id_autoLockTimer:
219 ++autoLockLock; 219 ++autoLockLock;
220 break; 220 break;
221 case id_metaCheckTimer: 221 case id_metaCheckTimer:
222 ++metaCheckLock; 222 ++metaCheckLock;
223 break; 223 break;
224 } 224 }
225} 225}
226 226
227void DocTimer::putLock(TimerIDs timer) 227void DocTimer::putLock(TimerIDs timer)
228{ 228{
229 switch (timer) { 229 switch (timer) {
230 case id_mpwTimer: 230 case id_mpwTimer:
231 if (mpwLock) 231 if (mpwLock)
232 --mpwLock; 232 --mpwLock;
233 break; 233 break;
234 case id_autoLockTimer: 234 case id_autoLockTimer:
235 if (autoLockLock) 235 if (autoLockLock)
236 --autoLockLock; 236 --autoLockLock;
237 break; 237 break;
238 case id_metaCheckTimer: 238 case id_metaCheckTimer:
239 if (metaCheckLock) 239 if (metaCheckLock)
240 --metaCheckLock; 240 --metaCheckLock;
241 break; 241 break;
242 } 242 }
243} 243}
244 244
245void DocTimer::mpwTimeout() 245void DocTimer::mpwTimeout()
246{ 246{
247 if (mpwLock) { 247 if (mpwLock) {
248 mpwTimer->start(1000, true); 248 mpwTimer->start(1000, true);
249 return; 249 return;
250 } 250 }
251 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 251 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
252} 252}
253 253
254void DocTimer::autoLockTimeout() 254void DocTimer::autoLockTimeout()
255{ 255{
256 if (autoLockLock) { 256 if (autoLockLock) {
257 autoLockTimer->start(1000, true); 257 autoLockTimer->start(1000, true);
258 return; 258 return;
259 } 259 }
260 if (conf()->confGlobAutoDeepLock() && 260 if (conf()->confGlobAutoDeepLock() &&
261 doc->filename != QString::null && 261 doc->filename != QString::null &&
262 doc->filename != "") { 262 doc->filename != "") {
263 doc->deepLock(true); 263 doc->deepLock(true);
264 } else { 264 } else {
265 doc->lockAll(true); 265 doc->lockAll(true);
266 } 266 }
267} 267}
268 268
269void DocTimer::metaCheckTimeout() 269void DocTimer::metaCheckTimeout()
270{ 270{
271 if (metaCheckLock) { 271 if (metaCheckLock) {
272 // check again in one second. 272 // check again in one second.
273 metaCheckTimer->start(1000, true); 273 metaCheckTimer->start(1000, true);
274 return; 274 return;
275 } 275 }
276 if (doc->isDeepLocked()) { 276 if (doc->isDeepLocked()) {
277 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 277 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
278 return; 278 return;
279 } 279 }
280 if (doc->isDocEmpty()) { 280 if (doc->isDocEmpty()) {
281 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 281 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
282 return; 282 return;
283 } 283 }
284#ifdef CONFIG_KWALLETIF 284#ifdef CONFIG_KWALLETIF
285 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 285 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
286 if (kwlEmu) 286 if (kwlEmu)
287 kwlEmu->suspendDocSignals(); 287 kwlEmu->suspendDocSignals();
288#endif // CONFIG_KWALLETIF 288#endif // CONFIG_KWALLETIF
289 /* We simply trigger all views to update their 289 /* We simply trigger all views to update their
290 * displayed values. This way they have a chance 290 * displayed values. This way they have a chance
291 * to get notified when some meta changes over time. 291 * to get notified when some meta changes over time.
292 * (for example an entry expired). 292 * (for example an entry expired).
293 * The _view_ is responsive for not updating its 293 * The _view_ is responsive for not updating its
294 * contents if nothing really changed! 294 * contents if nothing really changed!
295 */ 295 */
296 emit doc->dataChanged(doc); 296 emit doc->dataChanged(doc);
297#ifdef CONFIG_KWALLETIF 297#ifdef CONFIG_KWALLETIF
298 if (kwlEmu) 298 if (kwlEmu)
299 kwlEmu->resumeDocSignals(); 299 kwlEmu->resumeDocSignals();
300#endif // CONFIG_KWALLETIF 300#endif // CONFIG_KWALLETIF
301 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 301 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
302} 302}
303 303
304 304
305 305
306PwMDocList PwMDoc::openDocList; 306PwMDocList PwMDoc::openDocList;
307unsigned int PwMDocList::unnamedDocCnt = 1; 307unsigned int PwMDocList::unnamedDocCnt = 1;
308 308
309PwMDoc::PwMDoc(QObject *parent, const char *name) 309PwMDoc::PwMDoc(QObject *parent, const char *name)
310 : PwMDocUi(parent, name) 310 : PwMDocUi(parent, name)
311 , dataChangedLock (0) 311 , dataChangedLock (0)
312{ 312{
313 deleted = false; 313 deleted = false;
314 unnamedNum = 0; 314 unnamedNum = 0;
315 getOpenDocList()->add(this, getTitle().latin1()); 315 getOpenDocList()->add(this, getTitle().latin1());
316 curDocStat = 0; 316 curDocStat = 0;
317 setMaxNumEntries(); 317 setMaxNumEntries();
318 _timer = new DocTimer(this); 318 _timer = new DocTimer(this);
319 timer()->start(DocTimer::id_mpwTimer); 319 timer()->start(DocTimer::id_mpwTimer);
320 timer()->start(DocTimer::id_autoLockTimer); 320 timer()->start(DocTimer::id_autoLockTimer);
321 timer()->start(DocTimer::id_metaCheckTimer); 321 timer()->start(DocTimer::id_metaCheckTimer);
322 addCategory(DEFAULT_CATEGORY, 0, false); 322 addCategory(DEFAULT_CATEGORY, 0, false);
323 listView = 0; 323 listView = 0;
324 emit docCreated(this); 324 emit docCreated(this);
325} 325}
326 326
327PwMDoc::~PwMDoc() 327PwMDoc::~PwMDoc()
328{ 328{
329 emit docClosed(this); 329 emit docClosed(this);
330 getOpenDocList()->del(this); 330 getOpenDocList()->del(this);
331 delete _timer; 331 delete _timer;
332} 332}
333 333
334PwMerror PwMDoc::saveDoc(char compress, const QString *file) 334PwMerror PwMDoc::saveDoc(char compress, const QString *file)
335{ 335{
336 PwMerror ret, e; 336 PwMerror ret, e;
337 string serialized; 337 string serialized;
338 QFile f; 338 QFile f;
339 QString tmpFileMoved(QString::null); 339 QString tmpFileMoved(QString::null);
340 bool wasDeepLocked; 340 bool wasDeepLocked;
341 QString savedFilename(filename); 341 QString savedFilename(filename);
342 342
343 if (!file) { 343 if (!file) {
344 if (filename == "") 344 if (filename == "")
345 return e_filename; 345 return e_filename;
346 if (isDeepLocked()) { 346 if (isDeepLocked()) {
347 /* We don't need to save any data. 347 /* We don't need to save any data.
348 * It's already all on disk, because 348 * It's already all on disk, because
349 * we are deeplocked. 349 * we are deeplocked.
350 */ 350 */
351 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 351 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
352 ret = e_success; 352 ret = e_success;
353 return ret; 353 return ret;
354 } 354 }
355 } else { 355 } else {
356 if (*file == "" && filename == "") 356 if (*file == "" && filename == "")
357 return e_filename; 357 return e_filename;
358 if (*file != "") 358 if (*file != "")
359 filename = *file; 359 filename = *file;
360 } 360 }
361 361
362 wasDeepLocked = isDeepLocked(); 362 wasDeepLocked = isDeepLocked();
363 if (wasDeepLocked) { 363 if (wasDeepLocked) {
364 /* We are deeplocked. That means all data is already 364 /* We are deeplocked. That means all data is already
365 * on disk. BUT we need to do saving procedure, 365 * on disk. BUT we need to do saving procedure,
366 * because *file != savedFilename. 366 * because *file != savedFilename.
367 * Additionally we need to tempoarly restore 367 * Additionally we need to tempoarly restore
368 * the old "filename", because deepLock() references it. 368 * the old "filename", because deepLock() references it.
369 */ 369 */
370 QString newFilename(filename); 370 QString newFilename(filename);
371 filename = savedFilename; 371 filename = savedFilename;
372 getDataChangedLock(); 372 getDataChangedLock();
373 e = deepLock(false); 373 e = deepLock(false);
374 putDataChangedLock(); 374 putDataChangedLock();
375 filename = newFilename; 375 filename = newFilename;
376 switch (e) { 376 switch (e) {
377 case e_success: 377 case e_success:
378 break; 378 break;
379 case e_wrongPw: 379 case e_wrongPw:
380 case e_noPw: 380 case e_noPw:
381 emitDataChanged(this); 381 emitDataChanged(this);
382 return e; 382 return e;
383 default: 383 default:
384 emitDataChanged(this); 384 emitDataChanged(this);
385 return e_openFile; 385 return e_openFile;
386 } 386 }
387 } 387 }
388 388
389 if (!isPwAvailable()) { 389 if (!isPwAvailable()) {
390 /* password is not available. This means, the 390 /* password is not available. This means, the
391 * document wasn't saved, yet. 391 * document wasn't saved, yet.
392 */ 392 */
393 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 393 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
394 QString pw(requestNewMpw(&useChipcard)); 394 QString pw(requestNewMpw(&useChipcard));
395 if (pw != "") { 395 if (pw != "") {
396 currentPw = pw; 396 currentPw = pw;
397 } else { 397 } else {
398 return e_noPw; 398 return e_noPw;
399 } 399 }
400 if (useChipcard) { 400 if (useChipcard) {
401 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 401 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
402 } else { 402 } else {
403 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 403 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
404 } 404 }
405 } 405 }
406 406
407 int _cryptAlgo = conf()->confGlobCryptAlgo(); 407 int _cryptAlgo = conf()->confGlobCryptAlgo();
408 int _hashAlgo = conf()->confGlobHashAlgo(); 408 int _hashAlgo = conf()->confGlobHashAlgo();
409 409
410 // sanity check for the selected algorithms 410 // sanity check for the selected algorithms
411 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 411 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
412 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 412 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
413 printWarn("Invalid Crypto-Algorithm selected! " 413 printWarn("Invalid Crypto-Algorithm selected! "
414 "Config-file seems to be corrupt. " 414 "Config-file seems to be corrupt. "
415 "Falling back to Blowfish."); 415 "Falling back to Blowfish.");
416 _cryptAlgo = PWM_CRYPT_BLOWFISH; 416 _cryptAlgo = PWM_CRYPT_BLOWFISH;
417 } 417 }
418 if (_hashAlgo < PWM_HASH_SHA1 || 418 if (_hashAlgo < PWM_HASH_SHA1 ||
419 _hashAlgo > PWM_HASH_TIGER) { 419 _hashAlgo > PWM_HASH_TIGER) {
420 printWarn("Invalid Hash-Algorithm selected! " 420 printWarn("Invalid Hash-Algorithm selected! "
421 "Config-file seems to be corrupt. " 421 "Config-file seems to be corrupt. "
422 "Falling back to SHA1."); 422 "Falling back to SHA1.");
423 _hashAlgo = PWM_HASH_SHA1; 423 _hashAlgo = PWM_HASH_SHA1;
424 } 424 }
425 char cryptAlgo = static_cast<char>(_cryptAlgo); 425 char cryptAlgo = static_cast<char>(_cryptAlgo);
426 char hashAlgo = static_cast<char>(_hashAlgo); 426 char hashAlgo = static_cast<char>(_hashAlgo);
427 427
428 if (conf()->confGlobMakeFileBackup()) { 428 if (conf()->confGlobMakeFileBackup()) {
429 if (!backupFile(filename)) 429 if (!backupFile(filename))
430 return e_fileBackup; 430 return e_fileBackup;
431 } 431 }
432 int mLastBackupDate = 0; 432 int mLastBackupDate = 0;
433 KConfig configGlobal (locateLocal("config","pwmanagerbuprc")); 433 KConfig configGlobal (locateLocal("config","pwmanagerbuprc"));
434 QFileInfo fileInfo ( filename ); 434 QFileInfo fileInfo ( filename );
435 mLastBackupDate = configGlobal.readNumEntry( "LastBackupDate-"+ fileInfo.fileName (), 0 ); 435 mLastBackupDate = configGlobal.readNumEntry( "LastBackupDate-"+ fileInfo.fileName (), 0 );
436 KConfig config (locateLocal("config","microkdeglobalrc")); 436 KConfig config (locateLocal("config","microkdeglobalrc"));
437 config.setGroup( "BackupSettings" ); 437 config.setGroup( "BackupSettings" );
438 bool b_enabled = config.readBoolEntry( "BackupEnabled" ); 438 bool b_enabled = config.readBoolEntry( "BackupEnabled" );
439 if ( b_enabled ) { 439 if ( b_enabled && QFile::exists(filename)) {
440 int num = config.readNumEntry( "BackupNumbers" ); 440 int num = config.readNumEntry( "BackupNumbers" );
441 int d_count = config.readNumEntry( "BackupDayCount" ); 441 int d_count = config.readNumEntry( "BackupDayCount" );
442 bool stdDir = config.readBoolEntry( "BackupUseDefaultDir" ); 442 bool stdDir = config.readBoolEntry( "BackupUseDefaultDir" );
443 QString bupDir = config.readEntry( "BackupDatadir" ); 443 QString bupDir = config.readEntry( "BackupDatadir" );
444 QDate reference ( 2000,1,1 ); 444 QDate reference ( 2000,1,1 );
445 int daysTo = reference.daysTo ( QDate::currentDate() ); 445 int daysTo = reference.daysTo ( QDate::currentDate() );
446 bool saveDate = false; 446 bool saveDate = false;
447 if ( daysTo - d_count >= mLastBackupDate ) { 447 if ( daysTo - d_count >= mLastBackupDate ) {
448 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate ); 448 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
449 if ( stdDir ) 449 if ( stdDir )
450 bupDir = KGlobalSettings::backupDataDir(); 450 bupDir = KGlobalSettings::backupDataDir();
451 int retval = KApplication::createBackup( filename, bupDir, num ); 451 int retval = KApplication::createBackup( filename, bupDir, num );
452 if ( retval == 0 ) { 452 if ( retval == 0 ) {
453 qDebug("KO: Backup cancelled. Will try again tomorrow "); 453 qDebug("KO: Backup cancelled. Will try again tomorrow ");
454 // retval == 0 : backup skipped for today, try again tomorrow 454 // retval == 0 : backup skipped for today, try again tomorrow
455 mLastBackupDate = daysTo - d_count+1; 455 mLastBackupDate = daysTo - d_count+1;
456 saveDate = true; 456 saveDate = true;
457 } else if ( retval == 1 ){ 457 } else if ( retval == 1 ){
458 qDebug("KO: Backup created."); 458 qDebug("KO: Backup created.");
459 // backup ok 459 // backup ok
460 mLastBackupDate = daysTo; 460 mLastBackupDate = daysTo;
461 saveDate = true; 461 saveDate = true;
462 } else if ( retval == 2 ){ 462 } else if ( retval == 2 ){
463 qDebug("KO: Backup globally cancelled."); 463 qDebug("KO: Backup globally cancelled.");
464 // backup globally cancelled 464 // backup globally cancelled
465 b_enabled = false; 465 b_enabled = false;
466 } 466 }
467 if ( !b_enabled ) { 467 if ( !b_enabled ) {
468 config.writeEntry( "mBackupEnabled", false ); 468 config.writeEntry( "mBackupEnabled", false );
469 } 469 }
470 if ( saveDate ) { 470 if ( saveDate ) {
471 configGlobal.writeEntry( "LastBackupDate-"+ fileInfo.fileName (), mLastBackupDate ); 471 configGlobal.writeEntry( "LastBackupDate-"+ fileInfo.fileName (), mLastBackupDate );
472 } 472 }
473 } 473 }
474 } 474 }
475 if (QFile::exists(filename)) { 475 if (QFile::exists(filename)) {
476 /* Move the existing file to some tmp file. 476 /* Move the existing file to some tmp file.
477 * When saving file succeeds, delete tmp file. Otherwise 477 * When saving file succeeds, delete tmp file. Otherwise
478 * move tmp file back. See below. 478 * move tmp file back. See below.
479 */ 479 */
480 Randomizer *rnd = Randomizer::obj(); 480 Randomizer *rnd = Randomizer::obj();
481 char rnd_buf[5]; 481 char rnd_buf[5];
482 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 482 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
483 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 483 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
484 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 484 tmpFileMoved = filename + "." + rnd_buf + ".mv";
485 if (!copyFile(filename, tmpFileMoved)) 485 if (!copyFile(filename, tmpFileMoved))
486 return e_openFile; 486 return e_openFile;
487 if (!QFile::remove(filename)) { 487 if (!QFile::remove(filename)) {
488 printWarn(string("removing orig file ") 488 printWarn(string("removing orig file ")
489 + filename.latin1() 489 + filename.latin1()
490 + " failed!"); 490 + " failed!");
491 } 491 }
492 } 492 }
493 f.setName(filename); 493 f.setName(filename);
494 if (!f.open(IO_ReadWrite)) { 494 if (!f.open(IO_ReadWrite)) {
495 ret = e_openFile; 495 ret = e_openFile;
496 goto out_moveback; 496 goto out_moveback;
497 } 497 }
498 e = writeFileHeader(hashAlgo, hashAlgo, 498 e = writeFileHeader(hashAlgo, hashAlgo,
499 cryptAlgo, compress, 499 cryptAlgo, compress,
500 &currentPw, &f); 500 &currentPw, &f);
501 if (e == e_hashNotImpl) { 501 if (e == e_hashNotImpl) {
502 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 502 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
503 f.close(); 503 f.close();
504 ret = e_hashNotImpl; 504 ret = e_hashNotImpl;
505 goto out_moveback; 505 goto out_moveback;
506 } else if (e != e_success) { 506 } else if (e != e_success) {
507 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 507 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
508 f.close(); 508 f.close();
509 ret = e_writeHeader; 509 ret = e_writeHeader;
510 goto out_moveback; 510 goto out_moveback;
511 } 511 }
512 if (!serializeDta(&serialized)) { 512 if (!serializeDta(&serialized)) {
513 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 513 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
514 f.close(); 514 f.close();
515 ret = e_serializeDta; 515 ret = e_serializeDta;
516 goto out_moveback; 516 goto out_moveback;
517 } 517 }
518 e = writeDataHash(hashAlgo, &serialized, &f); 518 e = writeDataHash(hashAlgo, &serialized, &f);
519 if (e == e_hashNotImpl) { 519 if (e == e_hashNotImpl) {
520 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 520 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
521 f.close(); 521 f.close();
522 ret = e_hashNotImpl; 522 ret = e_hashNotImpl;
523 goto out_moveback; 523 goto out_moveback;
524 } else if (e != e_success) { 524 } else if (e != e_success) {
525 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 525 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
526 f.close(); 526 f.close();
527 ret = e_writeHeader; 527 ret = e_writeHeader;
528 goto out_moveback; 528 goto out_moveback;
529 } 529 }
530 if (!compressDta(&serialized, compress)) { 530 if (!compressDta(&serialized, compress)) {
531 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 531 printDebug("PwMDoc::saveDoc(): compressDta() failed");
532 f.close(); 532 f.close();
533 ret = e_enc; 533 ret = e_enc;
534 goto out_moveback; 534 goto out_moveback;
535 } 535 }
536 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo); 536 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
537 if (e == e_weakPw) { 537 if (e == e_weakPw) {
538 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 538 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
539 f.close(); 539 f.close();
540 ret = e_weakPw; 540 ret = e_weakPw;
541 goto out_moveback; 541 goto out_moveback;
542 } else if (e == e_cryptNotImpl) { 542 } else if (e == e_cryptNotImpl) {
543 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 543 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
544 f.close(); 544 f.close();
545 ret = e_cryptNotImpl; 545 ret = e_cryptNotImpl;
546 goto out_moveback; 546 goto out_moveback;
547 } else if (e != e_success) { 547 } else if (e != e_success) {
548 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 548 printDebug("PwMDoc::saveDoc(): encrypt() failed");
549 f.close(); 549 f.close();
550 ret = e_enc; 550 ret = e_enc;
551 goto out_moveback; 551 goto out_moveback;
552 } 552 }
553 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 553 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
554 f.close(); 554 f.close();
555#ifndef _WIN32_ 555#ifndef _WIN32_
556 if (chmod(filename.latin1(), 556 if (chmod(filename.latin1(),
557 conf()->confGlobFilePermissions())) { 557 conf()->confGlobFilePermissions())) {
558 printWarn(string("chmod failed: ") + strerror(errno)); 558 printWarn(string("chmod failed: ") + strerror(errno));
559 } 559 }
560#endif 560#endif
561 openDocList.edit(this, getTitle().latin1()); 561 openDocList.edit(this, getTitle().latin1());
562 if (wasDeepLocked) { 562 if (wasDeepLocked) {
563 /* Do _not_ save the data with the deepLock() 563 /* Do _not_ save the data with the deepLock()
564 * call, because this will recurse 564 * call, because this will recurse
565 * into saveDoc() 565 * into saveDoc()
566 */ 566 */
567 deepLock(true, false); 567 deepLock(true, false);
568 /* We don't check return value here, because 568 /* We don't check return value here, because
569 * it won't fail. See NOTE in deepLock() 569 * it won't fail. See NOTE in deepLock()
570 */ 570 */
571 } 571 }
572 if (tmpFileMoved != QString::null) { 572 if (tmpFileMoved != QString::null) {
573 // now remove the moved file. 573 // now remove the moved file.
574 if (!QFile::remove(tmpFileMoved)) { 574 if (!QFile::remove(tmpFileMoved)) {
575 printWarn(string("removing file ") 575 printWarn(string("removing file ")
576 + tmpFileMoved.latin1() 576 + tmpFileMoved.latin1()
577 + " failed!"); 577 + " failed!");
578 } 578 }
579 } 579 }
580 ret = e_success; 580 ret = e_success;
581 printDebug(string("writing file { name: ") 581 printDebug(string("writing file { name: ")
582 + filename.latin1() + " compress: " 582 + filename.latin1() + " compress: "
583 + tostr(static_cast<int>(compress)) + " cryptAlgo: " 583 + tostr(static_cast<int>(compress)) + " cryptAlgo: "
584 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " 584 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
585 + tostr(static_cast<int>(hashAlgo)) 585 + tostr(static_cast<int>(hashAlgo))
586 + " }"); 586 + " }");
587 goto out; 587 goto out;
588out_moveback: 588out_moveback:
589 if (tmpFileMoved != QString::null) { 589 if (tmpFileMoved != QString::null) {
590 if (copyFile(tmpFileMoved, filename)) { 590 if (copyFile(tmpFileMoved, filename)) {
591 if (!QFile::remove(tmpFileMoved)) { 591 if (!QFile::remove(tmpFileMoved)) {
592 printWarn(string("removing tmp file ") 592 printWarn(string("removing tmp file ")
593 + filename.latin1() 593 + filename.latin1()
594 + " failed!"); 594 + " failed!");
595 } 595 }
596 } else { 596 } else {
597 printWarn(string("couldn't copy file ") 597 printWarn(string("couldn't copy file ")
598 + tmpFileMoved.latin1() 598 + tmpFileMoved.latin1()
599 + " back to " 599 + " back to "
600 + filename.latin1()); 600 + filename.latin1());
601 } 601 }
602 } 602 }
603out: 603out:
604 return ret; 604 return ret;
605} 605}
606 606
607PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 607PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
608{ 608{
609 PWM_ASSERT(file); 609 PWM_ASSERT(file);
610 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 610 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
611 string decrypted, dataHash; 611 string decrypted, dataHash;
612 PwMerror ret; 612 PwMerror ret;
613 char cryptAlgo, dataHashType, compress; 613 char cryptAlgo, dataHashType, compress;
614 unsigned int headerLen; 614 unsigned int headerLen;
615 615
616 if (*file == "") 616 if (*file == "")
617 return e_readFile; 617 return e_readFile;
618 filename = *file; 618 filename = *file;
619 /* check if this file is already open. 619 /* check if this file is already open.
620 * This does not catch symlinks! 620 * This does not catch symlinks!
621 */ 621 */
622 if (!isDeepLocked()) { 622 if (!isDeepLocked()) {
623 if (getOpenDocList()->find(filename.latin1())) 623 if (getOpenDocList()->find(filename.latin1()))
624 return e_alreadyOpen; 624 return e_alreadyOpen;
625 } 625 }
626 QFile f(filename); 626 QFile f(filename);
627 627
628 if (openLocked == 2) { 628 if (openLocked == 2) {
629 // open deep-locked 629 // open deep-locked
630 if (!QFile::exists(filename)) 630 if (!QFile::exists(filename))
631 return e_openFile; 631 return e_openFile;
632 if (deepLock(true, false) != e_success) 632 if (deepLock(true, false) != e_success)
633 return e_openFile; 633 return e_openFile;
634 goto out_success; 634 goto out_success;
635 } 635 }
636 636
637 if (!f.open(IO_ReadOnly)) 637 if (!f.open(IO_ReadOnly))
638 return e_openFile; 638 return e_openFile;
639 639
640 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 640 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
641 &dataHashType, &dataHash, &f); 641 &dataHashType, &dataHash, &f);
642 if (ret != e_success) { 642 if (ret != e_success) {
643 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 643 printDebug("PwMDoc::openDoc(): checkHeader() failed");
644 f.close(); 644 f.close();
645 if (ret == e_wrongPw) { 645 if (ret == e_wrongPw) {
646 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 646 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
647 return ret; 647 return ret;
648 } else if (ret == e_noPw || 648 } else if (ret == e_noPw ||
649 ret == e_fileVer || 649 ret == e_fileVer ||
650 ret == e_fileFormat || 650 ret == e_fileFormat ||
651 ret == e_hashNotImpl) { 651 ret == e_hashNotImpl) {
652 return ret; 652 return ret;
653 } else 653 } else
654 return e_readFile; 654 return e_readFile;
655 } 655 }
656 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f); 656 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
657 if (ret == e_cryptNotImpl) { 657 if (ret == e_cryptNotImpl) {
658 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 658 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
659 f.close(); 659 f.close();
660 return e_cryptNotImpl; 660 return e_cryptNotImpl;
661 } else if (ret != e_success) { 661 } else if (ret != e_success) {
662 printDebug("PwMDoc::openDoc(): decrypt() failed"); 662 printDebug("PwMDoc::openDoc(): decrypt() failed");
663 f.close(); 663 f.close();
664 return e_readFile; 664 return e_readFile;
665 } 665 }
666 if (!decompressDta(&decrypted, compress)) { 666 if (!decompressDta(&decrypted, compress)) {
667 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 667 printDebug("PwMDoc::openDoc(): decompressDta() failed");
668 f.close(); 668 f.close();
669 return e_fileCorrupt; 669 return e_fileCorrupt;
670 } 670 }
671 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 671 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
672 if (ret == e_hashNotImpl) { 672 if (ret == e_hashNotImpl) {
673 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 673 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
674 f.close(); 674 f.close();
675 return e_hashNotImpl; 675 return e_hashNotImpl;
676 } else if (ret != e_success) { 676 } else if (ret != e_success) {
677 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 677 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
678 f.close(); 678 f.close();
679 return e_fileCorrupt; 679 return e_fileCorrupt;
680 } 680 }
681 if (!deSerializeDta(&decrypted, openLocked == 1)) { 681 if (!deSerializeDta(&decrypted, openLocked == 1)) {
682 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 682 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
683 f.close(); 683 f.close();
684 return e_readFile; 684 return e_readFile;
685 } 685 }
686 f.close(); 686 f.close();
687 timer()->start(DocTimer::id_mpwTimer); 687 timer()->start(DocTimer::id_mpwTimer);
688 timer()->start(DocTimer::id_autoLockTimer); 688 timer()->start(DocTimer::id_autoLockTimer);
689out_success: 689out_success:
690 openDocList.edit(this, getTitle().latin1()); 690 openDocList.edit(this, getTitle().latin1());
691 emit docOpened(this); 691 emit docOpened(this);
692 return e_success; 692 return e_success;
693} 693}
694 694
695PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 695PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
696 QString *pw, QFile *f) 696 QString *pw, QFile *f)
697{ 697{
698 PWM_ASSERT(pw); 698 PWM_ASSERT(pw);
699 PWM_ASSERT(f); 699 PWM_ASSERT(f);
700 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else 700 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
701 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion 701 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
702 //USPWM_ASSERT(listView); 702 //USPWM_ASSERT(listView);
703 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 703 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
704 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 704 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
705 return e_writeFile; 705 return e_writeFile;
706 } 706 }
707 if (f->putch(PWM_FILE_VER) == -1 || 707 if (f->putch(PWM_FILE_VER) == -1 ||
708 f->putch(keyHash) == -1 || 708 f->putch(keyHash) == -1 ||
709 f->putch(dataHash) == -1 || 709 f->putch(dataHash) == -1 ||
710 f->putch(crypt) == -1 || 710 f->putch(crypt) == -1 ||
711 f->putch(compress) == -1 || 711 f->putch(compress) == -1 ||
712 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 712 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
713 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 713 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
714 return e_writeFile; 714 return e_writeFile;
715 } 715 }
716 716
717 // write bytes of NUL-data. These bytes are reserved for future-use. 717 // write bytes of NUL-data. These bytes are reserved for future-use.
718 const int bufSize = 64; 718 const int bufSize = 64;
719 char tmp_buf[bufSize]; 719 char tmp_buf[bufSize];
720 memset(tmp_buf, 0x00, bufSize); 720 memset(tmp_buf, 0x00, bufSize);
721 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 721 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
722 return e_writeFile; 722 return e_writeFile;
723 723
724 switch (keyHash) { 724 switch (keyHash) {
725 case PWM_HASH_SHA1: { 725 case PWM_HASH_SHA1: {
726 const int hashlen = SHA1_HASH_LEN_BYTE; 726 const int hashlen = SHA1_HASH_LEN_BYTE;
727 Sha1 hash; 727 Sha1 hash;
728 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 728 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
729 string ret = hash.sha1_read(); 729 string ret = hash.sha1_read();
730 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 730 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
731 return e_writeFile; 731 return e_writeFile;
732 break; 732 break;
733 } 733 }
734 case PWM_HASH_SHA256: 734 case PWM_HASH_SHA256:
735 /*... fall through */ 735 /*... fall through */
736 case PWM_HASH_SHA384: 736 case PWM_HASH_SHA384:
737 case PWM_HASH_SHA512: 737 case PWM_HASH_SHA512:
738 case PWM_HASH_MD5: 738 case PWM_HASH_MD5:
739 case PWM_HASH_RMD160: 739 case PWM_HASH_RMD160:
740 case PWM_HASH_TIGER: 740 case PWM_HASH_TIGER:
741 { 741 {
742 if (!LibGCryptIf::available()) 742 if (!LibGCryptIf::available())
743 return e_hashNotImpl; 743 return e_hashNotImpl;
744 LibGCryptIf gc; 744 LibGCryptIf gc;
745 PwMerror err; 745 PwMerror err;
746 unsigned char *buf; 746 unsigned char *buf;
747 size_t hashLen; 747 size_t hashLen;
748 err = gc.hash(&buf, 748 err = gc.hash(&buf,
749 &hashLen, 749 &hashLen,
750 reinterpret_cast<const unsigned char *>(pw->latin1()), 750 reinterpret_cast<const unsigned char *>(pw->latin1()),
751 pw->length(), 751 pw->length(),
752 keyHash); 752 keyHash);
753 if (err != e_success) 753 if (err != e_success)
754 return e_hashNotImpl; 754 return e_hashNotImpl;
755 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 755 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
756 != static_cast<Q_LONG>(hashLen)) { 756 != static_cast<Q_LONG>(hashLen)) {
757 delete [] buf; 757 delete [] buf;
758 return e_hashNotImpl; 758 return e_hashNotImpl;
759 } 759 }
760 delete [] buf; 760 delete [] buf;
761 break; 761 break;
762 } 762 }
763 default: { 763 default: {
764 return e_hashNotImpl; 764 return e_hashNotImpl;
765 } } 765 } }
766 return e_success; 766 return e_success;
767} 767}
768 768
769PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 769PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
770 unsigned int *headerLength, char *dataHashType, 770 unsigned int *headerLength, char *dataHashType,
771 string *dataHash, QFile *f) 771 string *dataHash, QFile *f)
772{ 772{
773 PWM_ASSERT(cryptAlgo); 773 PWM_ASSERT(cryptAlgo);
774 PWM_ASSERT(pw); 774 PWM_ASSERT(pw);
775 PWM_ASSERT(headerLength); 775 PWM_ASSERT(headerLength);
776 PWM_ASSERT(dataHashType); 776 PWM_ASSERT(dataHashType);
777 PWM_ASSERT(dataHash); 777 PWM_ASSERT(dataHash);
778 PWM_ASSERT(f); 778 PWM_ASSERT(f);
779 int tmpRet; 779 int tmpRet;
780 // check "magic" header 780 // check "magic" header
781 const char magicHdr[] = FILE_ID_HEADER; 781 const char magicHdr[] = FILE_ID_HEADER;
782 const int hdrLen = array_size(magicHdr) - 1; 782 const int hdrLen = array_size(magicHdr) - 1;
783 char tmp[hdrLen]; 783 char tmp[hdrLen];
784 if (f->readBlock(tmp, hdrLen) != hdrLen) 784 if (f->readBlock(tmp, hdrLen) != hdrLen)
785 return e_readFile; 785 return e_readFile;
786 if (memcmp(tmp, magicHdr, hdrLen) != 0) 786 if (memcmp(tmp, magicHdr, hdrLen) != 0)
787 return e_fileFormat; 787 return e_fileFormat;
788 // read and check file ver 788 // read and check file ver
789 int fileV = f->getch(); 789 int fileV = f->getch();
790 if (fileV == -1) 790 if (fileV == -1)
791 return e_fileFormat; 791 return e_fileFormat;
792 if (fileV != PWM_FILE_VER) 792 if (fileV != PWM_FILE_VER)
793 return e_fileVer; 793 return e_fileVer;
794 // read hash hash type 794 // read hash hash type
795 int keyHash = f->getch(); 795 int keyHash = f->getch();
796 if (keyHash == -1) 796 if (keyHash == -1)
797 return e_fileFormat; 797 return e_fileFormat;
798 // read data hash type 798 // read data hash type
799 tmpRet = f->getch(); 799 tmpRet = f->getch();
800 if (tmpRet == -1) 800 if (tmpRet == -1)
801 return e_fileFormat; 801 return e_fileFormat;
802 *dataHashType = tmpRet; 802 *dataHashType = tmpRet;
803 // read crypt algo 803 // read crypt algo
804 tmpRet = f->getch(); 804 tmpRet = f->getch();
805 if (tmpRet == -1) 805 if (tmpRet == -1)
806 return e_fileFormat; 806 return e_fileFormat;
807 *cryptAlgo = tmpRet; 807 *cryptAlgo = tmpRet;
808 // get compression-algo 808 // get compression-algo
809 tmpRet = f->getch(); 809 tmpRet = f->getch();
810 if (tmpRet == -1) 810 if (tmpRet == -1)
811 return e_fileFormat; 811 return e_fileFormat;
812 *compress = tmpRet; 812 *compress = tmpRet;
813 // get the MPW-flag 813 // get the MPW-flag
814 int mpw_flag = f->getch(); 814 int mpw_flag = f->getch();
815 if (mpw_flag == -1) 815 if (mpw_flag == -1)
816 return e_fileFormat; 816 return e_fileFormat;
817 if (mpw_flag == 0x01) 817 if (mpw_flag == 0x01)
818 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 818 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
819 else 819 else
820 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 820 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
821 // skip the "RESERVED"-bytes 821 // skip the "RESERVED"-bytes
822 if (!(f->at(f->at() + 64))) 822 if (!(f->at(f->at() + 64)))
823 return e_fileFormat; 823 return e_fileFormat;
824 824
825 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 825 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
826 if (*pw == "") { 826 if (*pw == "") {
827 /* the user didn't give a master-password 827 /* the user didn't give a master-password
828 * or didn't insert a chipcard 828 * or didn't insert a chipcard
829 */ 829 */
830 return e_noPw; 830 return e_noPw;
831 } 831 }
832 // verify key-hash 832 // verify key-hash
833 switch (keyHash) { 833 switch (keyHash) {
834 case PWM_HASH_SHA1: { 834 case PWM_HASH_SHA1: {
835 // read hash from header 835 // read hash from header
836 const int hashLen = SHA1_HASH_LEN_BYTE; 836 const int hashLen = SHA1_HASH_LEN_BYTE;
837 string readHash; 837 string readHash;
838 int i; 838 int i;
839 for (i = 0; i < hashLen; ++i) 839 for (i = 0; i < hashLen; ++i)
840 readHash.push_back(f->getch()); 840 readHash.push_back(f->getch());
841 Sha1 hash; 841 Sha1 hash;
842 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 842 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
843 string ret = hash.sha1_read(); 843 string ret = hash.sha1_read();
844 if (ret != readHash) 844 if (ret != readHash)
845 return e_wrongPw;// hash doesn't match (wrong key) 845 return e_wrongPw;// hash doesn't match (wrong key)
846 break; 846 break;
847 } 847 }
848 case PWM_HASH_SHA256: 848 case PWM_HASH_SHA256:
849 /*... fall through */ 849 /*... fall through */
850 case PWM_HASH_SHA384: 850 case PWM_HASH_SHA384:
851 case PWM_HASH_SHA512: 851 case PWM_HASH_SHA512:
852 case PWM_HASH_MD5: 852 case PWM_HASH_MD5:
853 case PWM_HASH_RMD160: 853 case PWM_HASH_RMD160:
854 case PWM_HASH_TIGER: { 854 case PWM_HASH_TIGER: {
855 if (!LibGCryptIf::available()) 855 if (!LibGCryptIf::available())
856 return e_hashNotImpl; 856 return e_hashNotImpl;
857 LibGCryptIf gc; 857 LibGCryptIf gc;
858 PwMerror err; 858 PwMerror err;
859 unsigned char *buf; 859 unsigned char *buf;
860 size_t hashLen; 860 size_t hashLen;
861 err = gc.hash(&buf, 861 err = gc.hash(&buf,
862 &hashLen, 862 &hashLen,
863 reinterpret_cast<const unsigned char *>(pw->latin1()), 863 reinterpret_cast<const unsigned char *>(pw->latin1()),
864 pw->length(), 864 pw->length(),
865 keyHash); 865 keyHash);
866 if (err != e_success) 866 if (err != e_success)
867 return e_hashNotImpl; 867 return e_hashNotImpl;
868 string calcHash(reinterpret_cast<const char *>(buf), 868 string calcHash(reinterpret_cast<const char *>(buf),
869 static_cast<string::size_type>(hashLen)); 869 static_cast<string::size_type>(hashLen));
870 delete [] buf; 870 delete [] buf;
871 // read hash from header 871 // read hash from header
872 string readHash; 872 string readHash;
873 size_t i; 873 size_t i;
874 for (i = 0; i < hashLen; ++i) 874 for (i = 0; i < hashLen; ++i)
875 readHash.push_back(f->getch()); 875 readHash.push_back(f->getch());
876 if (calcHash != readHash) 876 if (calcHash != readHash)
877 return e_wrongPw;// hash doesn't match (wrong key) 877 return e_wrongPw;// hash doesn't match (wrong key)
878 break; 878 break;
879 } 879 }
880 default: { 880 default: {
881 return e_hashNotImpl; 881 return e_hashNotImpl;
882 } } 882 } }
883 // read the data-hash from the file 883 // read the data-hash from the file
884 unsigned int hashLen, i; 884 unsigned int hashLen, i;
885 switch (*dataHashType) { 885 switch (*dataHashType) {
886 case PWM_HASH_SHA1: 886 case PWM_HASH_SHA1:
887 hashLen = SHA1_HASH_LEN_BYTE; 887 hashLen = SHA1_HASH_LEN_BYTE;
888 break; 888 break;
889 case PWM_HASH_SHA256: 889 case PWM_HASH_SHA256:
890 /*... fall through */ 890 /*... fall through */
891 case PWM_HASH_SHA384: 891 case PWM_HASH_SHA384:
892 case PWM_HASH_SHA512: 892 case PWM_HASH_SHA512:
893 case PWM_HASH_MD5: 893 case PWM_HASH_MD5:
894 case PWM_HASH_RMD160: 894 case PWM_HASH_RMD160:
895 case PWM_HASH_TIGER: { 895 case PWM_HASH_TIGER: {
896 if (!LibGCryptIf::available()) 896 if (!LibGCryptIf::available())
897 return e_hashNotImpl; 897 return e_hashNotImpl;
898 LibGCryptIf gc; 898 LibGCryptIf gc;
899 hashLen = gc.hashLength(*dataHashType); 899 hashLen = gc.hashLength(*dataHashType);
900 if (hashLen == 0) 900 if (hashLen == 0)
901 return e_hashNotImpl; 901 return e_hashNotImpl;
902 break; 902 break;
903 } 903 }
904 default: 904 default:
905 return e_hashNotImpl; 905 return e_hashNotImpl;
906 } 906 }
907 *dataHash = ""; 907 *dataHash = "";
908 for (i = 0; i < hashLen; ++i) { 908 for (i = 0; i < hashLen; ++i) {
909 tmpRet = f->getch(); 909 tmpRet = f->getch();
910 if (tmpRet == -1) 910 if (tmpRet == -1)
911 return e_fileFormat; 911 return e_fileFormat;
912 dataHash->push_back(static_cast<char>(tmpRet)); 912 dataHash->push_back(static_cast<char>(tmpRet));
913 } 913 }
914 *headerLength = f->at(); 914 *headerLength = f->at();
915#ifndef PWM_EMBEDDED 915#ifndef PWM_EMBEDDED
916 printDebug(string("opening file { compress: ") 916 printDebug(string("opening file { compress: ")
917 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 917 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
918 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 918 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
919 + tostr(static_cast<int>(keyHash)) 919 + tostr(static_cast<int>(keyHash))
920 + " }"); 920 + " }");
921#else 921#else
922 printDebug(string("opening file { compress: ") 922 printDebug(string("opening file { compress: ")
923 + tostr((int)(*compress)) + " cryptAlgo: " 923 + tostr((int)(*compress)) + " cryptAlgo: "
924 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 924 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
925 + tostr((int)(keyHash)) 925 + tostr((int)(keyHash))
926 + " }"); 926 + " }");
927#endif 927#endif
928 928
929 return e_success; 929 return e_success;
930} 930}
931 931
932PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 932PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
933{ 933{
934 PWM_ASSERT(d); 934 PWM_ASSERT(d);
935 PWM_ASSERT(f); 935 PWM_ASSERT(f);
936 936
937 switch (dataHash) { 937 switch (dataHash) {
938 case PWM_HASH_SHA1: { 938 case PWM_HASH_SHA1: {
939 const int hashLen = SHA1_HASH_LEN_BYTE; 939 const int hashLen = SHA1_HASH_LEN_BYTE;
940 Sha1 h; 940 Sha1 h;
941 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 941 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
942 string hRet = h.sha1_read(); 942 string hRet = h.sha1_read();
943 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 943 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
944 return e_writeFile; 944 return e_writeFile;
945 break; 945 break;
946 } 946 }
947 case PWM_HASH_SHA256: 947 case PWM_HASH_SHA256:
948 /*... fall through */ 948 /*... fall through */
949 case PWM_HASH_SHA384: 949 case PWM_HASH_SHA384:
950 case PWM_HASH_SHA512: 950 case PWM_HASH_SHA512:
951 case PWM_HASH_MD5: 951 case PWM_HASH_MD5:
952 case PWM_HASH_RMD160: 952 case PWM_HASH_RMD160:
953 case PWM_HASH_TIGER: { 953 case PWM_HASH_TIGER: {
954 if (!LibGCryptIf::available()) 954 if (!LibGCryptIf::available())
955 return e_hashNotImpl; 955 return e_hashNotImpl;
956 LibGCryptIf gc; 956 LibGCryptIf gc;
957 PwMerror err; 957 PwMerror err;
958 unsigned char *buf; 958 unsigned char *buf;
959 size_t hashLen; 959 size_t hashLen;
960 err = gc.hash(&buf, 960 err = gc.hash(&buf,
961 &hashLen, 961 &hashLen,
962 reinterpret_cast<const unsigned char *>(d->c_str()), 962 reinterpret_cast<const unsigned char *>(d->c_str()),
963 d->size(), 963 d->size(),
964 dataHash); 964 dataHash);
965 if (err != e_success) 965 if (err != e_success)
966 return e_hashNotImpl; 966 return e_hashNotImpl;
967 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 967 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
968 != static_cast<Q_LONG>(hashLen)) { 968 != static_cast<Q_LONG>(hashLen)) {
969 delete [] buf; 969 delete [] buf;
970 return e_hashNotImpl; 970 return e_hashNotImpl;
971 } 971 }
972 delete [] buf; 972 delete [] buf;
973 break; 973 break;
974 } 974 }
975 default: { 975 default: {
976 return e_hashNotImpl; 976 return e_hashNotImpl;
977 } } 977 } }
978 978
979 return e_success; 979 return e_success;
980} 980}
981 981
982bool PwMDoc::backupFile(const QString &filePath) 982bool PwMDoc::backupFile(const QString &filePath)
983{ 983{
984 QFileInfo fi(filePath); 984 QFileInfo fi(filePath);
985 if (!fi.exists()) 985 if (!fi.exists())
986 return true; // Yes, true is correct. 986 return true; // Yes, true is correct.
987 QString pathOnly(fi.dirPath(true)); 987 QString pathOnly(fi.dirPath(true));
988 QString nameOnly(fi.fileName()); 988 QString nameOnly(fi.fileName());
989 QString backupPath = pathOnly 989 QString backupPath = pathOnly
990 + "/~" 990 + "/~"
991 + nameOnly 991 + nameOnly
992 + ".backup"; 992 + ".backup";
993 return copyFile(filePath, backupPath); 993 return copyFile(filePath, backupPath);
994} 994}
995 995
996bool PwMDoc::copyFile(const QString &src, const QString &dst) 996bool PwMDoc::copyFile(const QString &src, const QString &dst)
997{ 997{
998 QFileInfo fi(src); 998 QFileInfo fi(src);
999 if (!fi.exists()) 999 if (!fi.exists())
1000 return false; 1000 return false;
1001 if (QFile::exists(dst)) { 1001 if (QFile::exists(dst)) {
1002 if (!QFile::remove(dst)) 1002 if (!QFile::remove(dst))
1003 return false; 1003 return false;
1004 } 1004 }
1005 QFile srcFd(src); 1005 QFile srcFd(src);
1006 if (!srcFd.open(IO_ReadOnly)) 1006 if (!srcFd.open(IO_ReadOnly))
1007 return false; 1007 return false;
1008 QFile dstFd(dst); 1008 QFile dstFd(dst);
1009 if (!dstFd.open(IO_ReadWrite)) { 1009 if (!dstFd.open(IO_ReadWrite)) {
1010 srcFd.close(); 1010 srcFd.close();
1011 return false; 1011 return false;
1012 } 1012 }
1013 const int tmpBuf_size = 512; 1013 const int tmpBuf_size = 512;
1014 char tmpBuf[tmpBuf_size]; 1014 char tmpBuf[tmpBuf_size];
1015 Q_LONG bytesRead, bytesWritten; 1015 Q_LONG bytesRead, bytesWritten;
1016 1016
1017 while (!srcFd.atEnd()) { 1017 while (!srcFd.atEnd()) {
1018 bytesRead = srcFd.readBlock(tmpBuf, 1018 bytesRead = srcFd.readBlock(tmpBuf,
1019 static_cast<Q_ULONG>(tmpBuf_size)); 1019 static_cast<Q_ULONG>(tmpBuf_size));
1020 if (bytesRead == -1) { 1020 if (bytesRead == -1) {
1021 srcFd.close(); 1021 srcFd.close();
1022 dstFd.close(); 1022 dstFd.close();
1023 return false; 1023 return false;
1024 } 1024 }
1025 bytesWritten = dstFd.writeBlock(tmpBuf, 1025 bytesWritten = dstFd.writeBlock(tmpBuf,
1026 static_cast<Q_ULONG>(bytesRead)); 1026 static_cast<Q_ULONG>(bytesRead));
1027 if (bytesWritten != bytesRead) { 1027 if (bytesWritten != bytesRead) {
1028 srcFd.close(); 1028 srcFd.close();
1029 dstFd.close(); 1029 dstFd.close();
1030 return false; 1030 return false;
1031 } 1031 }
1032 } 1032 }
1033 srcFd.close(); 1033 srcFd.close();
1034 dstFd.close(); 1034 dstFd.close();
1035 return true; 1035 return true;
1036} 1036}
1037 1037
1038PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 1038PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
1039 bool dontFlagDirty, bool updateMeta) 1039 bool dontFlagDirty, bool updateMeta)
1040{ 1040{
1041 PWM_ASSERT(d); 1041 PWM_ASSERT(d);
1042 unsigned int cat = 0; 1042 unsigned int cat = 0;
1043 1043
1044 if (isDeepLocked()) { 1044 if (isDeepLocked()) {
1045 PwMerror ret; 1045 PwMerror ret;
1046 ret = deepLock(false); 1046 ret = deepLock(false);
1047 if (ret != e_success) 1047 if (ret != e_success)
1048 return e_lock; 1048 return e_lock;
1049 } 1049 }
1050 1050
1051 addCategory(category, &cat); 1051 addCategory(category, &cat);
1052 1052
1053 if (numEntries(category) >= maxEntries) 1053 if (numEntries(category) >= maxEntries)
1054 return e_maxAllowedEntr; 1054 return e_maxAllowedEntr;
1055 1055
1056 vector<unsigned int> foundPositions; 1056 vector<unsigned int> foundPositions;
1057 /* historically this was: 1057 /* historically this was:
1058 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 1058 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
1059 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 1059 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
1060 * But for now we only search in desc. 1060 * But for now we only search in desc.
1061 * That's a tweak to be KWallet compatible. But it should not add 1061 * That's a tweak to be KWallet compatible. But it should not add
1062 * usability-drop onto PwManager, does it? 1062 * usability-drop onto PwManager, does it?
1063 * (And yes, "int" was a bug. Correct is "unsigned int") 1063 * (And yes, "int" was a bug. Correct is "unsigned int")
1064 */ 1064 */
1065 const unsigned int searchIn = SEARCH_IN_DESC; 1065 const unsigned int searchIn = SEARCH_IN_DESC;
1066 findEntry(cat, *d, searchIn, &foundPositions, true); 1066 findEntry(cat, *d, searchIn, &foundPositions, true);
1067 if (foundPositions.size()) { 1067 if (foundPositions.size()) {
1068 // DOH! We found this entry. 1068 // DOH! We found this entry.
1069 return e_entryExists; 1069 return e_entryExists;
1070 } 1070 }
1071 1071
1072 d->listViewPos = -1; 1072 d->listViewPos = -1;
1073 d->lockStat = conf()->confGlobNewEntrLockStat(); 1073 d->lockStat = conf()->confGlobNewEntrLockStat();
1074 if (updateMeta) { 1074 if (updateMeta) {
1075 d->meta.create = QDateTime::currentDateTime(); 1075 d->meta.create = QDateTime::currentDateTime();
1076 d->meta.update = d->meta.create; 1076 d->meta.update = d->meta.create;
1077 } 1077 }
1078 dti.dta[cat].d.push_back(*d); 1078 dti.dta[cat].d.push_back(*d);
1079 1079
1080 delAllEmptyCat(true); 1080 delAllEmptyCat(true);
1081 1081
1082 if (!dontFlagDirty) 1082 if (!dontFlagDirty)
1083 flagDirty(); 1083 flagDirty();
1084 return e_success; 1084 return e_success;
1085} 1085}
1086 1086
1087PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 1087PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
1088 bool checkIfExist) 1088 bool checkIfExist)
1089{ 1089{
1090 if (isDeepLocked()) { 1090 if (isDeepLocked()) {
1091 PwMerror ret; 1091 PwMerror ret;
1092 ret = deepLock(false); 1092 ret = deepLock(false);
1093 if (ret != e_success) 1093 if (ret != e_success)
1094 return e_lock; 1094 return e_lock;
1095 } 1095 }
1096 if (checkIfExist) { 1096 if (checkIfExist) {
1097 if (findCategory(category, categoryIndex)) 1097 if (findCategory(category, categoryIndex))
1098 return e_categoryExists; 1098 return e_categoryExists;
1099 } 1099 }
1100 PwMCategoryItem item; 1100 PwMCategoryItem item;
1101 //US ENH: clear item to initialize with default values, or create a constructor 1101 //US ENH: clear item to initialize with default values, or create a constructor
1102 item.clear(); 1102 item.clear();
1103 1103
1104 item.name = category.latin1(); 1104 item.name = category.latin1();
1105 dti.dta.push_back(item); 1105 dti.dta.push_back(item);
1106 if (categoryIndex) 1106 if (categoryIndex)
1107 *categoryIndex = dti.dta.size() - 1; 1107 *categoryIndex = dti.dta.size() - 1;
1108 return e_success; 1108 return e_success;
1109} 1109}
1110 1110
1111bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1111bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1112{ 1112{
1113 unsigned int cat = 0; 1113 unsigned int cat = 0;
1114 1114
1115 if (!findCategory(category, &cat)) { 1115 if (!findCategory(category, &cat)) {
1116 BUG(); 1116 BUG();
1117 return false; 1117 return false;
1118 } 1118 }
1119 1119
1120 return delEntry(cat, index, dontFlagDirty); 1120 return delEntry(cat, index, dontFlagDirty);
1121} 1121}
1122 1122
1123bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1123bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1124{ 1124{
1125 if (isDeepLocked()) 1125 if (isDeepLocked())
1126 return false; 1126 return false;
1127 if (index > dti.dta[category].d.size() - 1) 1127 if (index > dti.dta[category].d.size() - 1)
1128 return false; 1128 return false;
1129 getDataChangedLock(); 1129 getDataChangedLock();
1130 if (!lockAt(category, index, false)) { 1130 if (!lockAt(category, index, false)) {
1131 putDataChangedLock(); 1131 putDataChangedLock();
1132 return false; 1132 return false;
1133 } 1133 }
1134 putDataChangedLock(); 1134 putDataChangedLock();
1135 int lvPos = dti.dta[category].d[index].listViewPos; 1135 int lvPos = dti.dta[category].d[index].listViewPos;
1136 1136
1137 // delete entry 1137 // delete entry
1138 dti.dta[category].d.erase(dti.dta[category].d.begin() + index); 1138 dti.dta[category].d.erase(dti.dta[category].d.begin() + index);
1139 1139
1140 unsigned int i, entries = numEntries(category); 1140 unsigned int i, entries = numEntries(category);
1141 if (!entries) { 1141 if (!entries) {
1142 // no more entries in this category, so 1142 // no more entries in this category, so
1143 // we can delete it, too. 1143 // we can delete it, too.
1144 BUG_ON(!delCategory(category)); 1144 BUG_ON(!delCategory(category));
1145 // delCategory() flags it dirty, so we need not to do so. 1145 // delCategory() flags it dirty, so we need not to do so.
1146 return true; 1146 return true;
1147 } 1147 }
1148 for (i = 0; i < entries; ++i) { 1148 for (i = 0; i < entries; ++i) {
1149 // decrement all listViewPositions that are greater than the deleted. 1149 // decrement all listViewPositions that are greater than the deleted.
1150 if (dti.dta[category].d[i].listViewPos > lvPos) 1150 if (dti.dta[category].d[i].listViewPos > lvPos)
1151 --dti.dta[category].d[i].listViewPos; 1151 --dti.dta[category].d[i].listViewPos;
1152 } 1152 }
1153 1153
1154 if (!dontFlagDirty) 1154 if (!dontFlagDirty)
1155 flagDirty(); 1155 flagDirty();
1156 return true; 1156 return true;
1157} 1157}
1158 1158
1159bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, 1159bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory,
1160 unsigned int index, PwMDataItem *d, bool updateMeta) 1160 unsigned int index, PwMDataItem *d, bool updateMeta)
1161{ 1161{
1162 PWM_ASSERT(d); 1162 PWM_ASSERT(d);
1163 unsigned int oldCat = 0; 1163 unsigned int oldCat = 0;
1164 1164
1165 if (!findCategory(oldCategory, &oldCat)) { 1165 if (!findCategory(oldCategory, &oldCat)) {
1166 BUG(); 1166 BUG();
1167 return false; 1167 return false;
1168 } 1168 }
1169 1169
1170 return editEntry(oldCat, newCategory, index, d, updateMeta); 1170 return editEntry(oldCat, newCategory, index, d, updateMeta);
1171} 1171}
1172 1172
1173bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, 1173bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory,
1174 unsigned int index, PwMDataItem *d, bool updateMeta) 1174 unsigned int index, PwMDataItem *d, bool updateMeta)
1175{ 1175{
1176 if (isDeepLocked()) 1176 if (isDeepLocked())
1177 return false; 1177 return false;
1178 if (updateMeta) { 1178 if (updateMeta) {
1179 d->meta.update = QDateTime::currentDateTime(); 1179 d->meta.update = QDateTime::currentDateTime();
1180 if (d->meta.create.isNull()) { 1180 if (d->meta.create.isNull()) {
1181 d->meta.create = d->meta.update; 1181 d->meta.create = d->meta.update;
1182 } 1182 }
1183 } 1183 }
1184 if (dti.dta[oldCategory].name != newCategory.latin1()) { 1184 if (dti.dta[oldCategory].name != newCategory.latin1()) {
1185 // the user changed the category. 1185 // the user changed the category.
1186 PwMerror ret; 1186 PwMerror ret;
1187 d->rev = 0; 1187 d->rev = 0;
1188 ret = addEntry(newCategory, d, true, false); 1188 ret = addEntry(newCategory, d, true, false);
1189 if (ret != e_success) 1189 if (ret != e_success)
1190 return false; 1190 return false;
1191 if (!delEntry(oldCategory, index, true)) 1191 if (!delEntry(oldCategory, index, true))
1192 return false; 1192 return false;
1193 } else { 1193 } else {
1194 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter. 1194 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter.
1195 dti.dta[oldCategory].d[index] = *d; 1195 dti.dta[oldCategory].d[index] = *d;
1196 } 1196 }
1197 flagDirty(); 1197 flagDirty();
1198 return true; 1198 return true;
1199} 1199}
1200 1200
1201unsigned int PwMDoc::numEntries(const QString &category) 1201unsigned int PwMDoc::numEntries(const QString &category)
1202{ 1202{
1203 unsigned int cat = 0; 1203 unsigned int cat = 0;
1204 1204
1205 if (!findCategory(category, &cat)) { 1205 if (!findCategory(category, &cat)) {
1206 BUG(); 1206 BUG();
1207 return 0; 1207 return 0;