summaryrefslogtreecommitdiffabout
authorulf69 <ulf69>2004-10-19 18:19:48 (UTC)
committer ulf69 <ulf69>2004-10-19 18:19:48 (UTC)
commit3b4dc5931f729bd1385ec83f8c9b82a1eb42ef36 (patch) (unidiff)
tree0c39138398640a7996ea4eea4c0f8196dbdc2bef
parent695c64501950e0503ed558fbe8d8c06993776eaa (diff)
downloadkdepimpi-3b4dc5931f729bd1385ec83f8c9b82a1eb42ef36.zip
kdepimpi-3b4dc5931f729bd1385ec83f8c9b82a1eb42ef36.tar.gz
kdepimpi-3b4dc5931f729bd1385ec83f8c9b82a1eb42ef36.tar.bz2
merging of two bugfixes provided by Michael:
1) files were getting stored always twice 2) "Save As..." returned a No permission dialogbox when executed right after starting the application
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp65
-rw-r--r--pwmanager/pwmanager/pwmdoc.h2
-rw-r--r--pwmanager/pwmanager/pwmdocui.cpp12
3 files changed, 67 insertions, 12 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index e9906a4..f4a1636 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,736 +1,778 @@
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 2.0 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 <libkcal/syncdefines.h> 38#include <libkcal/syncdefines.h>
39 39
40 40
41#ifdef CONFIG_KWALLETIF 41#ifdef CONFIG_KWALLETIF
42# include "kwalletemu.h" 42# include "kwalletemu.h"
43#endif // CONFIG_KWALLETIF 43#endif // CONFIG_KWALLETIF
44 44
45#include <qdatetime.h> 45#include <qdatetime.h>
46#include <qsize.h> 46#include <qsize.h>
47#include <qfileinfo.h> 47#include <qfileinfo.h>
48#include <qfile.h> 48#include <qfile.h>
49 49
50#include <stdio.h> 50#include <stdio.h>
51#include <stdlib.h> 51#include <stdlib.h>
52#include <errno.h> 52#include <errno.h>
53#include <string.h> 53#include <string.h>
54//US#include <iostream> 54//US#include <iostream>
55#include <algorithm> 55#include <algorithm>
56#include <sys/types.h> 56#include <sys/types.h>
57#include <sys/stat.h> 57#include <sys/stat.h>
58#include <unistd.h> 58#include <unistd.h>
59#include <stdint.h> 59#include <stdint.h>
60 60
61 61
62#ifdef PWM_EMBEDDED 62#ifdef PWM_EMBEDDED
63#ifndef Q_LONG 63#ifndef Q_LONG
64#define Q_LONG long 64#define Q_LONG long
65#endif 65#endif
66 66
67#ifndef Q_ULONG 67#ifndef Q_ULONG
68#define Q_ULONG unsigned long 68#define Q_ULONG unsigned long
69#endif 69#endif
70#endif //PWM_EMBEDDED 70#endif //PWM_EMBEDDED
71 71
72 72
73//TODO: reset to its normal value. 73//TODO: reset to its normal value.
74 #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */ 74 #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */
75 75
76using namespace std; 76using namespace std;
77 77
78 78
79void PwMDocList::add(PwMDoc *doc, const string &id) 79void PwMDocList::add(PwMDoc *doc, const string &id)
80{ 80{
81#ifdef PWM_DEBUG 81#ifdef PWM_DEBUG
82 // check for existance of object in debug mode only. 82 // check for existance of object in debug mode only.
83 vector<listItem>::iterator begin = docList.begin(), 83 vector<listItem>::iterator begin = docList.begin(),
84 end = docList.end(), 84 end = docList.end(),
85 i = begin; 85 i = begin;
86 while (i != end) { 86 while (i != end) {
87 if (i->doc == doc) { 87 if (i->doc == doc) {
88 BUG(); 88 BUG();
89 return; 89 return;
90 } 90 }
91 ++i; 91 ++i;
92 } 92 }
93#endif 93#endif
94 listItem newItem; 94 listItem newItem;
95 newItem.doc = doc; 95 newItem.doc = doc;
96 newItem.docId = id; 96 newItem.docId = id;
97 docList.push_back(newItem); 97 docList.push_back(newItem);
98} 98}
99 99
100void PwMDocList::edit(PwMDoc *doc, const string &newId) 100void PwMDocList::edit(PwMDoc *doc, const string &newId)
101{ 101{
102 vector<listItem>::iterator begin = docList.begin(), 102 vector<listItem>::iterator begin = docList.begin(),
103 end = docList.end(), 103 end = docList.end(),
104 i = begin; 104 i = begin;
105 while (i != end) { 105 while (i != end) {
106 if (i->doc == doc) { 106 if (i->doc == doc) {
107 i->docId = newId; 107 i->docId = newId;
108 return; 108 return;
109 } 109 }
110 ++i; 110 ++i;
111 } 111 }
112} 112}
113 113
114void PwMDocList::del(PwMDoc *doc) 114void PwMDocList::del(PwMDoc *doc)
115{ 115{
116 vector<listItem>::iterator begin = docList.begin(), 116 vector<listItem>::iterator begin = docList.begin(),
117 end = docList.end(), 117 end = docList.end(),
118 i = begin; 118 i = begin;
119 while (i != end) { 119 while (i != end) {
120 if (i->doc == doc) { 120 if (i->doc == doc) {
121 docList.erase(i); 121 docList.erase(i);
122 return; 122 return;
123 } 123 }
124 ++i; 124 ++i;
125 } 125 }
126} 126}
127 127
128bool PwMDocList::find(const string &id, listItem *ret) 128bool PwMDocList::find(const string &id, listItem *ret)
129{ 129{
130 vector<listItem>::iterator begin = docList.begin(), 130 vector<listItem>::iterator begin = docList.begin(),
131 end = docList.end(), 131 end = docList.end(),
132 i = begin; 132 i = begin;
133 while (i != end) { 133 while (i != end) {
134 if (i->docId == id) { 134 if (i->docId == id) {
135 if (ret) 135 if (ret)
136 *ret = *i; 136 *ret = *i;
137 return true; 137 return true;
138 } 138 }
139 ++i; 139 ++i;
140 } 140 }
141 return false; 141 return false;
142} 142}
143 143
144 144
145 145
146DocTimer::DocTimer(PwMDoc *_doc) 146DocTimer::DocTimer(PwMDoc *_doc)
147 : doc (_doc) 147 : doc (_doc)
148 , mpwLock (0) 148 , mpwLock (0)
149 , autoLockLock (0) 149 , autoLockLock (0)
150 , metaCheckLock (0) 150 , metaCheckLock (0)
151{ 151{
152 mpwTimer = new QTimer; 152 mpwTimer = new QTimer;
153 autoLockTimer = new QTimer; 153 autoLockTimer = new QTimer;
154 metaCheckTimer = new QTimer; 154 metaCheckTimer = new QTimer;
155 connect(mpwTimer, SIGNAL(timeout()), 155 connect(mpwTimer, SIGNAL(timeout()),
156 this, SLOT(mpwTimeout())); 156 this, SLOT(mpwTimeout()));
157 connect(autoLockTimer, SIGNAL(timeout()), 157 connect(autoLockTimer, SIGNAL(timeout()),
158 this, SLOT(autoLockTimeout())); 158 this, SLOT(autoLockTimeout()));
159 connect(metaCheckTimer, SIGNAL(timeout()), 159 connect(metaCheckTimer, SIGNAL(timeout()),
160 this, SLOT(metaCheckTimeout())); 160 this, SLOT(metaCheckTimeout()));
161} 161}
162 162
163DocTimer::~DocTimer() 163DocTimer::~DocTimer()
164{ 164{
165 delete mpwTimer; 165 delete mpwTimer;
166 delete autoLockTimer; 166 delete autoLockTimer;
167 delete metaCheckTimer; 167 delete metaCheckTimer;
168} 168}
169 169
170void DocTimer::start(TimerIDs timer) 170void DocTimer::start(TimerIDs timer)
171{ 171{
172 switch (timer) { 172 switch (timer) {
173 case id_mpwTimer: 173 case id_mpwTimer:
174 if (mpwTimer->isActive()) 174 if (mpwTimer->isActive())
175 mpwTimer->stop(); 175 mpwTimer->stop();
176 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 176 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
177 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); 177 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
178 break; 178 break;
179 case id_autoLockTimer: 179 case id_autoLockTimer:
180 if (autoLockTimer->isActive()) 180 if (autoLockTimer->isActive())
181 autoLockTimer->stop(); 181 autoLockTimer->stop();
182 if (conf()->confGlobLockTimeout() > 0) 182 if (conf()->confGlobLockTimeout() > 0)
183 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); 183 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
184 break; 184 break;
185 case id_metaCheckTimer: 185 case id_metaCheckTimer:
186 if (metaCheckTimer->isActive()) 186 if (metaCheckTimer->isActive())
187 metaCheckTimer->stop(); 187 metaCheckTimer->stop();
188 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 188 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
189 break; 189 break;
190 } 190 }
191} 191}
192 192
193void DocTimer::stop(TimerIDs timer) 193void DocTimer::stop(TimerIDs timer)
194{ 194{
195 switch (timer) { 195 switch (timer) {
196 case id_mpwTimer: 196 case id_mpwTimer:
197 mpwTimer->stop(); 197 mpwTimer->stop();
198 break; 198 break;
199 case id_autoLockTimer: 199 case id_autoLockTimer:
200 autoLockTimer->stop(); 200 autoLockTimer->stop();
201 break; 201 break;
202 case id_metaCheckTimer: 202 case id_metaCheckTimer:
203 metaCheckTimer->stop(); 203 metaCheckTimer->stop();
204 break; 204 break;
205 } 205 }
206} 206}
207 207
208void DocTimer::getLock(TimerIDs timer) 208void DocTimer::getLock(TimerIDs timer)
209{ 209{
210 switch (timer) { 210 switch (timer) {
211 case id_mpwTimer: 211 case id_mpwTimer:
212 ++mpwLock; 212 ++mpwLock;
213 break; 213 break;
214 case id_autoLockTimer: 214 case id_autoLockTimer:
215 ++autoLockLock; 215 ++autoLockLock;
216 break; 216 break;
217 case id_metaCheckTimer: 217 case id_metaCheckTimer:
218 ++metaCheckLock; 218 ++metaCheckLock;
219 break; 219 break;
220 } 220 }
221} 221}
222 222
223void DocTimer::putLock(TimerIDs timer) 223void DocTimer::putLock(TimerIDs timer)
224{ 224{
225 switch (timer) { 225 switch (timer) {
226 case id_mpwTimer: 226 case id_mpwTimer:
227 if (mpwLock) 227 if (mpwLock)
228 --mpwLock; 228 --mpwLock;
229 break; 229 break;
230 case id_autoLockTimer: 230 case id_autoLockTimer:
231 if (autoLockLock) 231 if (autoLockLock)
232 --autoLockLock; 232 --autoLockLock;
233 break; 233 break;
234 case id_metaCheckTimer: 234 case id_metaCheckTimer:
235 if (metaCheckLock) 235 if (metaCheckLock)
236 --metaCheckLock; 236 --metaCheckLock;
237 break; 237 break;
238 } 238 }
239} 239}
240 240
241void DocTimer::mpwTimeout() 241void DocTimer::mpwTimeout()
242{ 242{
243 if (mpwLock) { 243 if (mpwLock) {
244 mpwTimer->start(1000, true); 244 mpwTimer->start(1000, true);
245 return; 245 return;
246 } 246 }
247 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 247 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
248} 248}
249 249
250void DocTimer::autoLockTimeout() 250void DocTimer::autoLockTimeout()
251{ 251{
252 if (autoLockLock) { 252 if (autoLockLock) {
253 autoLockTimer->start(1000, true); 253 autoLockTimer->start(1000, true);
254 return; 254 return;
255 } 255 }
256 if (conf()->confGlobAutoDeepLock() && 256 if (conf()->confGlobAutoDeepLock() &&
257 doc->filename != QString::null && 257 doc->filename != QString::null &&
258 doc->filename != "") { 258 doc->filename != "") {
259 doc->deepLock(true); 259 doc->deepLock(true);
260 } else { 260 } else {
261 doc->lockAll(true); 261 doc->lockAll(true);
262 } 262 }
263} 263}
264 264
265void DocTimer::metaCheckTimeout() 265void DocTimer::metaCheckTimeout()
266{ 266{
267 if (metaCheckLock) { 267 if (metaCheckLock) {
268 // check again in one second. 268 // check again in one second.
269 metaCheckTimer->start(1000, true); 269 metaCheckTimer->start(1000, true);
270 return; 270 return;
271 } 271 }
272 if (doc->isDeepLocked()) { 272 if (doc->isDeepLocked()) {
273 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 273 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
274 return; 274 return;
275 } 275 }
276 if (doc->isDocEmpty()) { 276 if (doc->isDocEmpty()) {
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#ifdef CONFIG_KWALLETIF 280#ifdef CONFIG_KWALLETIF
281 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 281 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
282 if (kwlEmu) 282 if (kwlEmu)
283 kwlEmu->suspendDocSignals(); 283 kwlEmu->suspendDocSignals();
284#endif // CONFIG_KWALLETIF 284#endif // CONFIG_KWALLETIF
285 /* We simply trigger all views to update their 285 /* We simply trigger all views to update their
286 * displayed values. This way they have a chance 286 * displayed values. This way they have a chance
287 * to get notified when some meta changes over time. 287 * to get notified when some meta changes over time.
288 * (for example an entry expired). 288 * (for example an entry expired).
289 * The _view_ is responsive for not updating its 289 * The _view_ is responsive for not updating its
290 * contents if nothing really changed! 290 * contents if nothing really changed!
291 */ 291 */
292 emit doc->dataChanged(doc); 292 emit doc->dataChanged(doc);
293#ifdef CONFIG_KWALLETIF 293#ifdef CONFIG_KWALLETIF
294 if (kwlEmu) 294 if (kwlEmu)
295 kwlEmu->resumeDocSignals(); 295 kwlEmu->resumeDocSignals();
296#endif // CONFIG_KWALLETIF 296#endif // CONFIG_KWALLETIF
297 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 297 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
298} 298}
299 299
300 300
301 301
302PwMDocList PwMDoc::openDocList; 302PwMDocList PwMDoc::openDocList;
303unsigned int PwMDocList::unnamedDocCnt = 1; 303unsigned int PwMDocList::unnamedDocCnt = 1;
304 304
305PwMDoc::PwMDoc(QObject *parent, const char *name) 305PwMDoc::PwMDoc(QObject *parent, const char *name)
306 : PwMDocUi(parent, name) 306 : PwMDocUi(parent, name)
307 , dataChangedLock (0) 307 , dataChangedLock (0)
308{ 308{
309 deleted = false; 309 deleted = false;
310 unnamedNum = 0; 310 unnamedNum = 0;
311 getOpenDocList()->add(this, getTitle().latin1()); 311 getOpenDocList()->add(this, getTitle().latin1());
312 curDocStat = 0; 312 curDocStat = 0;
313 setMaxNumEntries(); 313 setMaxNumEntries();
314 _timer = new DocTimer(this); 314 _timer = new DocTimer(this);
315 timer()->start(DocTimer::id_mpwTimer); 315 timer()->start(DocTimer::id_mpwTimer);
316 timer()->start(DocTimer::id_autoLockTimer); 316 timer()->start(DocTimer::id_autoLockTimer);
317 timer()->start(DocTimer::id_metaCheckTimer); 317 timer()->start(DocTimer::id_metaCheckTimer);
318 addCategory(DEFAULT_CATEGORY, 0, false); 318 addCategory(DEFAULT_CATEGORY, 0, false);
319 listView = 0; 319 listView = 0;
320 emit docCreated(this); 320 emit docCreated(this);
321} 321}
322 322
323PwMDoc::~PwMDoc() 323PwMDoc::~PwMDoc()
324{ 324{
325 emit docClosed(this); 325 emit docClosed(this);
326 getOpenDocList()->del(this); 326 getOpenDocList()->del(this);
327 delete _timer; 327 delete _timer;
328} 328}
329 329
330PwMerror PwMDoc::saveDoc(char compress, const QString *file) 330PwMerror PwMDoc::saveDoc(char compress, const QString *file)
331{ 331{
332 PwMerror ret, e; 332 PwMerror ret, e;
333 string serialized;
334 QFile f;
335 QString tmpFileMoved(QString::null);
336 bool wasDeepLocked;
337 QString savedFilename(filename);
338
333 if (!file) { 339 if (!file) {
334 if (filename == "") 340 if (filename == "")
335 return e_filename; 341 return e_filename;
336 } else { 342 if (isDeepLocked()) {
343 /* We don't need to save any data.
344 * It's already all on disk, because
345 * we are deeplocked.
346 */
347 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
348 ret = e_success;
349 goto out;
350 }
351 } else {
337 if (*file == "" && filename == "") 352 if (*file == "" && filename == "")
338 return e_filename; 353 return e_filename;
339 if (*file != "") 354 if (*file != "")
340 filename = *file; 355 filename = *file;
341 } 356 }
342 357
343 bool wasDeepLocked = isDeepLocked(); 358 wasDeepLocked = isDeepLocked();
344 if (wasDeepLocked) { 359 if (wasDeepLocked) {
345 if (deepLock(false) != e_success) 360 /* We are deeplocked. That means all data is already
346 return e_noPw; 361 * on disk. BUT we need to do saving procedure,
362 * because *file != savedFilename.
363 * Additionally we need to tempoarly restore
364 * the old "filename", because deepLock() references it.
365 */
366 QString newFilename(filename);
367 filename = savedFilename;
368 getDataChangedLock();
369 e = deepLock(false);
370 putDataChangedLock();
371 filename = newFilename;
372 switch (e) {
373 case e_success:
374 break;
375 case e_wrongPw:
376 case e_noPw:
377 emitDataChanged(this);
378 return e;
379 default:
380 emitDataChanged(this);
381 return e_openFile;
382 }
347 } 383 }
348 384
349 if (!isPwAvailable()) { 385 if (!isPwAvailable()) {
350 /* password is not available. This means, the 386 /* password is not available. This means, the
351 * document wasn't saved, yet. 387 * document wasn't saved, yet.
352 */ 388 */
353 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 389 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
354 QString pw(requestNewMpw(&useChipcard)); 390 QString pw(requestNewMpw(&useChipcard));
355 if (pw != "") { 391 if (pw != "") {
356 currentPw = pw; 392 currentPw = pw;
357 } else { 393 } else {
358 return e_noPw; 394 return e_noPw;
359 } 395 }
360 if (useChipcard) { 396 if (useChipcard) {
361 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 397 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
362 } else { 398 } else {
363 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 399 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
364 } 400 }
365 } 401 }
366 402
367 int _cryptAlgo = conf()->confGlobCryptAlgo(); 403 int _cryptAlgo = conf()->confGlobCryptAlgo();
368 int _hashAlgo = conf()->confGlobHashAlgo(); 404 int _hashAlgo = conf()->confGlobHashAlgo();
369 405
370 // sanity check for the selected algorithms 406 // sanity check for the selected algorithms
371 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 407 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
372 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 408 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
373 printWarn("Invalid Crypto-Algorithm selected! " 409 printWarn("Invalid Crypto-Algorithm selected! "
374 "Config-file seems to be corrupt. " 410 "Config-file seems to be corrupt. "
375 "Falling back to Blowfish."); 411 "Falling back to Blowfish.");
376 _cryptAlgo = PWM_CRYPT_BLOWFISH; 412 _cryptAlgo = PWM_CRYPT_BLOWFISH;
377 } 413 }
378 if (_hashAlgo < PWM_HASH_SHA1 || 414 if (_hashAlgo < PWM_HASH_SHA1 ||
379 _hashAlgo > PWM_HASH_TIGER) { 415 _hashAlgo > PWM_HASH_TIGER) {
380 printWarn("Invalid Hash-Algorithm selected! " 416 printWarn("Invalid Hash-Algorithm selected! "
381 "Config-file seems to be corrupt. " 417 "Config-file seems to be corrupt. "
382 "Falling back to SHA1."); 418 "Falling back to SHA1.");
383 _hashAlgo = PWM_HASH_SHA1; 419 _hashAlgo = PWM_HASH_SHA1;
384 } 420 }
385 char cryptAlgo = static_cast<char>(_cryptAlgo); 421 char cryptAlgo = static_cast<char>(_cryptAlgo);
386 char hashAlgo = static_cast<char>(_hashAlgo); 422 char hashAlgo = static_cast<char>(_hashAlgo);
387 423
388 if (conf()->confGlobMakeFileBackup()) { 424 if (conf()->confGlobMakeFileBackup()) {
389 if (!backupFile(filename)) 425 if (!backupFile(filename))
390 return e_fileBackup; 426 return e_fileBackup;
391 } 427 }
392 QString tmpFileMoved(QString::null);
393 if (QFile::exists(filename)) { 428 if (QFile::exists(filename)) {
394 /* Move the existing file to some tmp file. 429 /* Move the existing file to some tmp file.
395 * When saving file succeeds, delete tmp file. Otherwise 430 * When saving file succeeds, delete tmp file. Otherwise
396 * move tmp file back. See below. 431 * move tmp file back. See below.
397 */ 432 */
398 Randomizer *rnd = Randomizer::obj(); 433 Randomizer *rnd = Randomizer::obj();
399 char rnd_buf[5]; 434 char rnd_buf[5];
400 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 435 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
401 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 436 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
402 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 437 tmpFileMoved = filename + "." + rnd_buf + ".mv";
403 if (!copyFile(filename, tmpFileMoved)) 438 if (!copyFile(filename, tmpFileMoved))
404 return e_openFile; 439 return e_openFile;
405 if (!QFile::remove(filename)) { 440 if (!QFile::remove(filename)) {
406 printWarn(string("removing orig file ") 441 printWarn(string("removing orig file ")
407 + filename.latin1() 442 + filename.latin1()
408 + " failed!"); 443 + " failed!");
409 } 444 }
410 } 445 }
411 QFile f(filename); 446 f.setName(filename);
412 string serialized;
413 if (!f.open(IO_ReadWrite)) { 447 if (!f.open(IO_ReadWrite)) {
414 ret = e_openFile; 448 ret = e_openFile;
415 goto out_moveback; 449 goto out_moveback;
416 } 450 }
417 e = writeFileHeader(hashAlgo, hashAlgo, 451 e = writeFileHeader(hashAlgo, hashAlgo,
418 cryptAlgo, compress, 452 cryptAlgo, compress,
419 &currentPw, &f); 453 &currentPw, &f);
420 if (e == e_hashNotImpl) { 454 if (e == e_hashNotImpl) {
421 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 455 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
422 f.close(); 456 f.close();
423 ret = e_hashNotImpl; 457 ret = e_hashNotImpl;
424 goto out_moveback; 458 goto out_moveback;
425 } else if (e != e_success) { 459 } else if (e != e_success) {
426 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 460 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
427 f.close(); 461 f.close();
428 ret = e_writeHeader; 462 ret = e_writeHeader;
429 goto out_moveback; 463 goto out_moveback;
430 } 464 }
431 if (!serializeDta(&serialized)) { 465 if (!serializeDta(&serialized)) {
432 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 466 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
433 f.close(); 467 f.close();
434 ret = e_serializeDta; 468 ret = e_serializeDta;
435 goto out_moveback; 469 goto out_moveback;
436 } 470 }
437 e = writeDataHash(hashAlgo, &serialized, &f); 471 e = writeDataHash(hashAlgo, &serialized, &f);
438 if (e == e_hashNotImpl) { 472 if (e == e_hashNotImpl) {
439 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 473 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
440 f.close(); 474 f.close();
441 ret = e_hashNotImpl; 475 ret = e_hashNotImpl;
442 goto out_moveback; 476 goto out_moveback;
443 } else if (e != e_success) { 477 } else if (e != e_success) {
444 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 478 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
445 f.close(); 479 f.close();
446 ret = e_writeHeader; 480 ret = e_writeHeader;
447 goto out_moveback; 481 goto out_moveback;
448 } 482 }
449 if (!compressDta(&serialized, compress)) { 483 if (!compressDta(&serialized, compress)) {
450 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 484 printDebug("PwMDoc::saveDoc(): compressDta() failed");
451 f.close(); 485 f.close();
452 ret = e_enc; 486 ret = e_enc;
453 goto out_moveback; 487 goto out_moveback;
454 } 488 }
455 e = encrypt(&serialized, &currentPw, &f, cryptAlgo); 489 e = encrypt(&serialized, &currentPw, &f, cryptAlgo);
456 if (e == e_weakPw) { 490 if (e == e_weakPw) {
457 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 491 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
458 f.close(); 492 f.close();
459 ret = e_weakPw; 493 ret = e_weakPw;
460 goto out_moveback; 494 goto out_moveback;
461 } else if (e == e_cryptNotImpl) { 495 } else if (e == e_cryptNotImpl) {
462 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 496 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
463 f.close(); 497 f.close();
464 ret = e_cryptNotImpl; 498 ret = e_cryptNotImpl;
465 goto out_moveback; 499 goto out_moveback;
466 } else if (e != e_success) { 500 } else if (e != e_success) {
467 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 501 printDebug("PwMDoc::saveDoc(): encrypt() failed");
468 f.close(); 502 f.close();
469 ret = e_enc; 503 ret = e_enc;
470 goto out_moveback; 504 goto out_moveback;
471 } 505 }
472 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 506 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
473 f.close(); 507 f.close();
474 if (chmod(filename.latin1(), 508 if (chmod(filename.latin1(),
475 conf()->confGlobFilePermissions())) { 509 conf()->confGlobFilePermissions())) {
476 printWarn(string("chmod failed: ") + strerror(errno)); 510 printWarn(string("chmod failed: ") + strerror(errno));
477 } 511 }
478 openDocList.edit(this, getTitle().latin1()); 512 openDocList.edit(this, getTitle().latin1());
479 if (wasDeepLocked) 513 if (wasDeepLocked) {
480 deepLock(true); 514 /* Do _not_ save the data with the deepLock()
515 * call, because this will recurse
516 * into saveDoc()
517 */
518 deepLock(true, false);
519 /* We don't check return value here, because
520 * it won't fail. See NOTE in deepLock()
521 */
522 }
481 if (tmpFileMoved != QString::null) { 523 if (tmpFileMoved != QString::null) {
482 // now remove the moved file. 524 // now remove the moved file.
483 if (!QFile::remove(tmpFileMoved)) { 525 if (!QFile::remove(tmpFileMoved)) {
484 printWarn(string("removing file ") 526 printWarn(string("removing file ")
485 + tmpFileMoved.latin1() 527 + tmpFileMoved.latin1()
486 + " failed!"); 528 + " failed!");
487 } 529 }
488 } 530 }
489 ret = e_success; 531 ret = e_success;
490 printDebug(string("writing file { name: ") 532 printDebug(string("writing file { name: ")
491 + filename.latin1() + " compress: " 533 + filename.latin1() + " compress: "
492 + tostr(static_cast<int>(compress)) + " cryptAlgo: " 534 + tostr(static_cast<int>(compress)) + " cryptAlgo: "
493 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " 535 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
494 + tostr(static_cast<int>(hashAlgo)) 536 + tostr(static_cast<int>(hashAlgo))
495 + " }"); 537 + " }");
496 goto out; 538 goto out;
497out_moveback: 539out_moveback:
498 if (tmpFileMoved != QString::null) { 540 if (tmpFileMoved != QString::null) {
499 if (copyFile(tmpFileMoved, filename)) { 541 if (copyFile(tmpFileMoved, filename)) {
500 if (!QFile::remove(tmpFileMoved)) { 542 if (!QFile::remove(tmpFileMoved)) {
501 printWarn(string("removing tmp file ") 543 printWarn(string("removing tmp file ")
502 + filename.latin1() 544 + filename.latin1()
503 + " failed!"); 545 + " failed!");
504 } 546 }
505 } else { 547 } else {
506 printWarn(string("couldn't copy file ") 548 printWarn(string("couldn't copy file ")
507 + tmpFileMoved.latin1() 549 + tmpFileMoved.latin1()
508 + " back to " 550 + " back to "
509 + filename.latin1()); 551 + filename.latin1());
510 } 552 }
511 } 553 }
512out: 554out:
513 return ret; 555 return ret;
514} 556}
515 557
516PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 558PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
517{ 559{
518 PWM_ASSERT(file); 560 PWM_ASSERT(file);
519 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 561 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
520 string decrypted, dataHash; 562 string decrypted, dataHash;
521 PwMerror ret; 563 PwMerror ret;
522 char cryptAlgo, dataHashType, compress; 564 char cryptAlgo, dataHashType, compress;
523 unsigned int headerLen; 565 unsigned int headerLen;
524 566
525 if (*file == "") 567 if (*file == "")
526 return e_readFile; 568 return e_readFile;
527 filename = *file; 569 filename = *file;
528 /* check if this file is already open. 570 /* check if this file is already open.
529 * This does not catch symlinks! 571 * This does not catch symlinks!
530 */ 572 */
531 if (!isDeepLocked()) { 573 if (!isDeepLocked()) {
532 if (getOpenDocList()->find(filename.latin1())) 574 if (getOpenDocList()->find(filename.latin1()))
533 return e_alreadyOpen; 575 return e_alreadyOpen;
534 } 576 }
535 QFile f(filename); 577 QFile f(filename);
536 578
537 if (openLocked == 2) { 579 if (openLocked == 2) {
538 // open deep-locked 580 // open deep-locked
539 if (!QFile::exists(filename)) 581 if (!QFile::exists(filename))
540 return e_openFile; 582 return e_openFile;
541 if (deepLock(true, false) != e_success) 583 if (deepLock(true, false) != e_success)
542 return e_openFile; 584 return e_openFile;
543 goto out_success; 585 goto out_success;
544 } 586 }
545 587
546 if (!f.open(IO_ReadOnly)) 588 if (!f.open(IO_ReadOnly))
547 return e_openFile; 589 return e_openFile;
548 590
549 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 591 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
550 &dataHashType, &dataHash, &f); 592 &dataHashType, &dataHash, &f);
551 if (ret != e_success) { 593 if (ret != e_success) {
552 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 594 printDebug("PwMDoc::openDoc(): checkHeader() failed");
553 f.close(); 595 f.close();
554 if (ret == e_wrongPw) { 596 if (ret == e_wrongPw) {
555 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 597 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
556 return ret; 598 return ret;
557 } else if (ret == e_noPw || 599 } else if (ret == e_noPw ||
558 ret == e_fileVer || 600 ret == e_fileVer ||
559 ret == e_fileFormat || 601 ret == e_fileFormat ||
560 ret == e_hashNotImpl) { 602 ret == e_hashNotImpl) {
561 return ret; 603 return ret;
562 } else 604 } else
563 return e_readFile; 605 return e_readFile;
564 } 606 }
565 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f); 607 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f);
566 if (ret == e_cryptNotImpl) { 608 if (ret == e_cryptNotImpl) {
567 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 609 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
568 f.close(); 610 f.close();
569 return e_cryptNotImpl; 611 return e_cryptNotImpl;
570 } else if (ret != e_success) { 612 } else if (ret != e_success) {
571 printDebug("PwMDoc::openDoc(): decrypt() failed"); 613 printDebug("PwMDoc::openDoc(): decrypt() failed");
572 f.close(); 614 f.close();
573 return e_readFile; 615 return e_readFile;
574 } 616 }
575 if (!decompressDta(&decrypted, compress)) { 617 if (!decompressDta(&decrypted, compress)) {
576 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 618 printDebug("PwMDoc::openDoc(): decompressDta() failed");
577 f.close(); 619 f.close();
578 return e_fileCorrupt; 620 return e_fileCorrupt;
579 } 621 }
580 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 622 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
581 if (ret == e_hashNotImpl) { 623 if (ret == e_hashNotImpl) {
582 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 624 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
583 f.close(); 625 f.close();
584 return e_hashNotImpl; 626 return e_hashNotImpl;
585 } else if (ret != e_success) { 627 } else if (ret != e_success) {
586 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 628 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
587 f.close(); 629 f.close();
588 return e_fileCorrupt; 630 return e_fileCorrupt;
589 } 631 }
590 if (!deSerializeDta(&decrypted, openLocked == 1)) { 632 if (!deSerializeDta(&decrypted, openLocked == 1)) {
591 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 633 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
592 f.close(); 634 f.close();
593 return e_readFile; 635 return e_readFile;
594 } 636 }
595 f.close(); 637 f.close();
596 timer()->start(DocTimer::id_mpwTimer); 638 timer()->start(DocTimer::id_mpwTimer);
597 timer()->start(DocTimer::id_autoLockTimer); 639 timer()->start(DocTimer::id_autoLockTimer);
598out_success: 640out_success:
599 openDocList.edit(this, getTitle().latin1()); 641 openDocList.edit(this, getTitle().latin1());
600 emit docOpened(this); 642 emit docOpened(this);
601 return e_success; 643 return e_success;
602} 644}
603 645
604PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 646PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
605 QString *pw, QFile *f) 647 QString *pw, QFile *f)
606{ 648{
607 PWM_ASSERT(pw); 649 PWM_ASSERT(pw);
608 PWM_ASSERT(f); 650 PWM_ASSERT(f);
609 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else 651 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
610 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion 652 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
611 //USPWM_ASSERT(listView); 653 //USPWM_ASSERT(listView);
612 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 654 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
613 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 655 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
614 return e_writeFile; 656 return e_writeFile;
615 } 657 }
616 if (f->putch(PWM_FILE_VER) == -1 || 658 if (f->putch(PWM_FILE_VER) == -1 ||
617 f->putch(keyHash) == -1 || 659 f->putch(keyHash) == -1 ||
618 f->putch(dataHash) == -1 || 660 f->putch(dataHash) == -1 ||
619 f->putch(crypt) == -1 || 661 f->putch(crypt) == -1 ||
620 f->putch(compress) == -1 || 662 f->putch(compress) == -1 ||
621 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 663 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
622 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 664 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
623 return e_writeFile; 665 return e_writeFile;
624 } 666 }
625 667
626 // write bytes of NUL-data. These bytes are reserved for future-use. 668 // write bytes of NUL-data. These bytes are reserved for future-use.
627 const int bufSize = 64; 669 const int bufSize = 64;
628 char tmp_buf[bufSize]; 670 char tmp_buf[bufSize];
629 memset(tmp_buf, 0x00, bufSize); 671 memset(tmp_buf, 0x00, bufSize);
630 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 672 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
631 return e_writeFile; 673 return e_writeFile;
632 674
633 switch (keyHash) { 675 switch (keyHash) {
634 case PWM_HASH_SHA1: { 676 case PWM_HASH_SHA1: {
635 const int hashlen = SHA1_HASH_LEN_BYTE; 677 const int hashlen = SHA1_HASH_LEN_BYTE;
636 Sha1 hash; 678 Sha1 hash;
637 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 679 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
638 string ret = hash.sha1_read(); 680 string ret = hash.sha1_read();
639 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 681 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
640 return e_writeFile; 682 return e_writeFile;
641 break; 683 break;
642 } 684 }
643 case PWM_HASH_SHA256: 685 case PWM_HASH_SHA256:
644 /*... fall through */ 686 /*... fall through */
645 case PWM_HASH_SHA384: 687 case PWM_HASH_SHA384:
646 case PWM_HASH_SHA512: 688 case PWM_HASH_SHA512:
647 case PWM_HASH_MD5: 689 case PWM_HASH_MD5:
648 case PWM_HASH_RMD160: 690 case PWM_HASH_RMD160:
649 case PWM_HASH_TIGER: 691 case PWM_HASH_TIGER:
650 { 692 {
651 if (!LibGCryptIf::available()) 693 if (!LibGCryptIf::available())
652 return e_hashNotImpl; 694 return e_hashNotImpl;
653 LibGCryptIf gc; 695 LibGCryptIf gc;
654 PwMerror err; 696 PwMerror err;
655 unsigned char *buf; 697 unsigned char *buf;
656 size_t hashLen; 698 size_t hashLen;
657 err = gc.hash(&buf, 699 err = gc.hash(&buf,
658 &hashLen, 700 &hashLen,
659 reinterpret_cast<const unsigned char *>(pw->latin1()), 701 reinterpret_cast<const unsigned char *>(pw->latin1()),
660 pw->length(), 702 pw->length(),
661 keyHash); 703 keyHash);
662 if (err != e_success) 704 if (err != e_success)
663 return e_hashNotImpl; 705 return e_hashNotImpl;
664 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 706 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
665 != static_cast<Q_LONG>(hashLen)) { 707 != static_cast<Q_LONG>(hashLen)) {
666 delete [] buf; 708 delete [] buf;
667 return e_hashNotImpl; 709 return e_hashNotImpl;
668 } 710 }
669 delete [] buf; 711 delete [] buf;
670 break; 712 break;
671 } 713 }
672 default: { 714 default: {
673 return e_hashNotImpl; 715 return e_hashNotImpl;
674 } } 716 } }
675 return e_success; 717 return e_success;
676} 718}
677 719
678PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 720PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
679 unsigned int *headerLength, char *dataHashType, 721 unsigned int *headerLength, char *dataHashType,
680 string *dataHash, QFile *f) 722 string *dataHash, QFile *f)
681{ 723{
682 PWM_ASSERT(cryptAlgo); 724 PWM_ASSERT(cryptAlgo);
683 PWM_ASSERT(pw); 725 PWM_ASSERT(pw);
684 PWM_ASSERT(headerLength); 726 PWM_ASSERT(headerLength);
685 PWM_ASSERT(dataHashType); 727 PWM_ASSERT(dataHashType);
686 PWM_ASSERT(dataHash); 728 PWM_ASSERT(dataHash);
687 PWM_ASSERT(f); 729 PWM_ASSERT(f);
688 int tmpRet; 730 int tmpRet;
689 // check "magic" header 731 // check "magic" header
690 const char magicHdr[] = FILE_ID_HEADER; 732 const char magicHdr[] = FILE_ID_HEADER;
691 const int hdrLen = array_size(magicHdr) - 1; 733 const int hdrLen = array_size(magicHdr) - 1;
692 char tmp[hdrLen]; 734 char tmp[hdrLen];
693 if (f->readBlock(tmp, hdrLen) != hdrLen) 735 if (f->readBlock(tmp, hdrLen) != hdrLen)
694 return e_readFile; 736 return e_readFile;
695 if (memcmp(tmp, magicHdr, hdrLen) != 0) 737 if (memcmp(tmp, magicHdr, hdrLen) != 0)
696 return e_fileFormat; 738 return e_fileFormat;
697 // read and check file ver 739 // read and check file ver
698 int fileV = f->getch(); 740 int fileV = f->getch();
699 if (fileV == -1) 741 if (fileV == -1)
700 return e_fileFormat; 742 return e_fileFormat;
701 if (fileV != PWM_FILE_VER) 743 if (fileV != PWM_FILE_VER)
702 return e_fileVer; 744 return e_fileVer;
703 // read hash hash type 745 // read hash hash type
704 int keyHash = f->getch(); 746 int keyHash = f->getch();
705 if (keyHash == -1) 747 if (keyHash == -1)
706 return e_fileFormat; 748 return e_fileFormat;
707 // read data hash type 749 // read data hash type
708 tmpRet = f->getch(); 750 tmpRet = f->getch();
709 if (tmpRet == -1) 751 if (tmpRet == -1)
710 return e_fileFormat; 752 return e_fileFormat;
711 *dataHashType = tmpRet; 753 *dataHashType = tmpRet;
712 // read crypt algo 754 // read crypt algo
713 tmpRet = f->getch(); 755 tmpRet = f->getch();
714 if (tmpRet == -1) 756 if (tmpRet == -1)
715 return e_fileFormat; 757 return e_fileFormat;
716 *cryptAlgo = tmpRet; 758 *cryptAlgo = tmpRet;
717 // get compression-algo 759 // get compression-algo
718 tmpRet = f->getch(); 760 tmpRet = f->getch();
719 if (tmpRet == -1) 761 if (tmpRet == -1)
720 return e_fileFormat; 762 return e_fileFormat;
721 *compress = tmpRet; 763 *compress = tmpRet;
722 // get the MPW-flag 764 // get the MPW-flag
723 int mpw_flag = f->getch(); 765 int mpw_flag = f->getch();
724 if (mpw_flag == -1) 766 if (mpw_flag == -1)
725 return e_fileFormat; 767 return e_fileFormat;
726 if (mpw_flag == 0x01) 768 if (mpw_flag == 0x01)
727 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 769 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
728 else 770 else
729 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 771 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
730 // skip the "RESERVED"-bytes 772 // skip the "RESERVED"-bytes
731 if (!(f->at(f->at() + 64))) 773 if (!(f->at(f->at() + 64)))
732 return e_fileFormat; 774 return e_fileFormat;
733 775
734 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 776 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
735 if (*pw == "") { 777 if (*pw == "") {
736 /* the user didn't give a master-password 778 /* the user didn't give a master-password
@@ -1516,512 +1558,515 @@ bool PwMDoc::lockAll(bool lock)
1516 } 1558 }
1517 if (!lock && currentPw != "") { 1559 if (!lock && currentPw != "") {
1518 // unlocking and password is already set 1560 // unlocking and password is already set
1519 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1561 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1520 // unlocking without pw not allowed 1562 // unlocking without pw not allowed
1521 QString pw; 1563 QString pw;
1522 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1564 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1523 if (pw != "") { 1565 if (pw != "") {
1524 if (pw != currentPw) { 1566 if (pw != currentPw) {
1525 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1567 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1526 return false; 1568 return false;
1527 } else { 1569 } else {
1528 timer()->start(DocTimer::id_mpwTimer); 1570 timer()->start(DocTimer::id_mpwTimer);
1529 } 1571 }
1530 } else { 1572 } else {
1531 return false; 1573 return false;
1532 } 1574 }
1533 } else { 1575 } else {
1534 timer()->start(DocTimer::id_mpwTimer); 1576 timer()->start(DocTimer::id_mpwTimer);
1535 } 1577 }
1536 } 1578 }
1537 1579
1538 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1580 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1539 catEnd = dti.dta.end(), 1581 catEnd = dti.dta.end(),
1540 catI = catBegin; 1582 catI = catBegin;
1541 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1583 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1542 while (catI != catEnd) { 1584 while (catI != catEnd) {
1543 entrBegin = catI->d.begin(); 1585 entrBegin = catI->d.begin();
1544 entrEnd = catI->d.end(); 1586 entrEnd = catI->d.end();
1545 entrI = entrBegin; 1587 entrI = entrBegin;
1546 while (entrI != entrEnd) { 1588 while (entrI != entrEnd) {
1547 entrI->lockStat = lock; 1589 entrI->lockStat = lock;
1548 entrI->rev++; // increment revision counter. 1590 entrI->rev++; // increment revision counter.
1549 ++entrI; 1591 ++entrI;
1550 } 1592 }
1551 ++catI; 1593 ++catI;
1552 } 1594 }
1553 1595
1554 emitDataChanged(this); 1596 emitDataChanged(this);
1555 if (lock) 1597 if (lock)
1556 timer()->stop(DocTimer::id_autoLockTimer); 1598 timer()->stop(DocTimer::id_autoLockTimer);
1557 else 1599 else
1558 timer()->start(DocTimer::id_autoLockTimer); 1600 timer()->start(DocTimer::id_autoLockTimer);
1559 1601
1560 return true; 1602 return true;
1561} 1603}
1562 1604
1563bool PwMDoc::isLocked(const QString &category, unsigned int index) 1605bool PwMDoc::isLocked(const QString &category, unsigned int index)
1564{ 1606{
1565 unsigned int cat = 0; 1607 unsigned int cat = 0;
1566 1608
1567 if (!findCategory(category, &cat)) { 1609 if (!findCategory(category, &cat)) {
1568 BUG(); 1610 BUG();
1569 return false; 1611 return false;
1570 } 1612 }
1571 1613
1572 return isLocked(cat, index); 1614 return isLocked(cat, index);
1573} 1615}
1574 1616
1575bool PwMDoc::unlockAll_tempoary(bool revert) 1617bool PwMDoc::unlockAll_tempoary(bool revert)
1576{ 1618{
1577 static vector< vector<bool> > *oldLockStates = 0; 1619 static vector< vector<bool> > *oldLockStates = 0;
1578 static bool wasDeepLocked; 1620 static bool wasDeepLocked;
1579 1621
1580 if (revert) {// revert the unlocking 1622 if (revert) {// revert the unlocking
1581 if (oldLockStates) { 1623 if (oldLockStates) {
1582 /* we actually _have_ unlocked something, because 1624 /* we actually _have_ unlocked something, because
1583 * we have allocated space for the oldLockStates. 1625 * we have allocated space for the oldLockStates.
1584 * So, go on and revert them! 1626 * So, go on and revert them!
1585 */ 1627 */
1586 if (wasDeepLocked) { 1628 if (wasDeepLocked) {
1587 PwMerror ret = deepLock(true); 1629 PwMerror ret = deepLock(true);
1588 if (ret == e_success) { 1630 if (ret == e_success) {
1589 /* deep-lock succeed. We are save. 1631 /* deep-lock succeed. We are save.
1590 * (but if it failed, just go on 1632 * (but if it failed, just go on
1591 * lock them normally) 1633 * lock them normally)
1592 */ 1634 */
1593 delete_and_null(oldLockStates); 1635 delete_and_null(oldLockStates);
1594 timer()->start(DocTimer::id_autoLockTimer); 1636 timer()->start(DocTimer::id_autoLockTimer);
1595 printDebug("tempoary unlocking of dta " 1637 printDebug("tempoary unlocking of dta "
1596 "reverted by deep-locking."); 1638 "reverted by deep-locking.");
1597 return true; 1639 return true;
1598 } 1640 }
1599 printDebug("deep-lock failed while reverting! " 1641 printDebug("deep-lock failed while reverting! "
1600 "Falling back to normal-lock."); 1642 "Falling back to normal-lock.");
1601 } 1643 }
1602 if (unlikely(!wasDeepLocked && 1644 if (unlikely(!wasDeepLocked &&
1603 numCategories() != oldLockStates->size())) { 1645 numCategories() != oldLockStates->size())) {
1604 /* DOH! We have modified "dta" while 1646 /* DOH! We have modified "dta" while
1605 * it was unlocked tempoary. DON'T DO THIS! 1647 * it was unlocked tempoary. DON'T DO THIS!
1606 */ 1648 */
1607 BUG(); 1649 BUG();
1608 delete_and_null(oldLockStates); 1650 delete_and_null(oldLockStates);
1609 timer()->start(DocTimer::id_autoLockTimer); 1651 timer()->start(DocTimer::id_autoLockTimer);
1610 return false; 1652 return false;
1611 } 1653 }
1612 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1654 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1613 catEnd = dti.dta.end(), 1655 catEnd = dti.dta.end(),
1614 catI = catBegin; 1656 catI = catBegin;
1615 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1657 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1616 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); 1658 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin();
1617 vector<bool>::iterator oldEntrStatBegin, 1659 vector<bool>::iterator oldEntrStatBegin,
1618 oldEntrStatEnd, 1660 oldEntrStatEnd,
1619 oldEntrStatI; 1661 oldEntrStatI;
1620 while (catI != catEnd) { 1662 while (catI != catEnd) {
1621 entrBegin = catI->d.begin(); 1663 entrBegin = catI->d.begin();
1622 entrEnd = catI->d.end(); 1664 entrEnd = catI->d.end();
1623 entrI = entrBegin; 1665 entrI = entrBegin;
1624 if (likely(!wasDeepLocked)) { 1666 if (likely(!wasDeepLocked)) {
1625 oldEntrStatBegin = oldCatStatI->begin(); 1667 oldEntrStatBegin = oldCatStatI->begin();
1626 oldEntrStatEnd = oldCatStatI->end(); 1668 oldEntrStatEnd = oldCatStatI->end();
1627 oldEntrStatI = oldEntrStatBegin; 1669 oldEntrStatI = oldEntrStatBegin;
1628 if (unlikely(catI->d.size() != oldCatStatI->size())) { 1670 if (unlikely(catI->d.size() != oldCatStatI->size())) {
1629 /* DOH! We have modified "dta" while 1671 /* DOH! We have modified "dta" while
1630 * it was unlocked tempoary. DON'T DO THIS! 1672 * it was unlocked tempoary. DON'T DO THIS!
1631 */ 1673 */
1632 BUG(); 1674 BUG();
1633 delete_and_null(oldLockStates); 1675 delete_and_null(oldLockStates);
1634 timer()->start(DocTimer::id_autoLockTimer); 1676 timer()->start(DocTimer::id_autoLockTimer);
1635 return false; 1677 return false;
1636 } 1678 }
1637 } 1679 }
1638 while (entrI != entrEnd) { 1680 while (entrI != entrEnd) {
1639 if (wasDeepLocked) { 1681 if (wasDeepLocked) {
1640 /* this is an error-fallback if 1682 /* this is an error-fallback if
1641 * deeplock didn't succeed 1683 * deeplock didn't succeed
1642 */ 1684 */
1643 entrI->lockStat = true; 1685 entrI->lockStat = true;
1644 } else { 1686 } else {
1645 entrI->lockStat = *oldEntrStatI; 1687 entrI->lockStat = *oldEntrStatI;
1646 } 1688 }
1647 ++entrI; 1689 ++entrI;
1648 if (likely(!wasDeepLocked)) 1690 if (likely(!wasDeepLocked))
1649 ++oldEntrStatI; 1691 ++oldEntrStatI;
1650 } 1692 }
1651 ++catI; 1693 ++catI;
1652 if (likely(!wasDeepLocked)) 1694 if (likely(!wasDeepLocked))
1653 ++oldCatStatI; 1695 ++oldCatStatI;
1654 } 1696 }
1655 delete_and_null(oldLockStates); 1697 delete_and_null(oldLockStates);
1656 if (unlikely(wasDeepLocked)) { 1698 if (unlikely(wasDeepLocked)) {
1657 /* error fallback... */ 1699 /* error fallback... */
1658 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1700 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1659 emitDataChanged(this); 1701 emitDataChanged(this);
1660 printDebug("WARNING: unlockAll_tempoary(true) " 1702 printDebug("WARNING: unlockAll_tempoary(true) "
1661 "deeplock fallback!"); 1703 "deeplock fallback!");
1662 } 1704 }
1663 printDebug("tempoary unlocking of dta reverted."); 1705 printDebug("tempoary unlocking of dta reverted.");
1664 } else { 1706 } else {
1665 printDebug("unlockAll_tempoary(true): nothing to do."); 1707 printDebug("unlockAll_tempoary(true): nothing to do.");
1666 } 1708 }
1667 timer()->start(DocTimer::id_autoLockTimer); 1709 timer()->start(DocTimer::id_autoLockTimer);
1668 } else {// unlock all data tempoary 1710 } else {// unlock all data tempoary
1669 if (unlikely(oldLockStates != 0)) { 1711 if (unlikely(oldLockStates != 0)) {
1670 /* DOH! We have already unlocked the data tempoarly. 1712 /* DOH! We have already unlocked the data tempoarly.
1671 * No need to do it twice. ;) 1713 * No need to do it twice. ;)
1672 */ 1714 */
1673 BUG(); 1715 BUG();
1674 return false; 1716 return false;
1675 } 1717 }
1676 wasDeepLocked = false; 1718 wasDeepLocked = false;
1677 bool mustUnlock = false; 1719 bool mustUnlock = false;
1678 if (isDeepLocked()) { 1720 if (isDeepLocked()) {
1679 PwMerror ret; 1721 PwMerror ret;
1680 while (1) { 1722 while (1) {
1681 ret = deepLock(false); 1723 ret = deepLock(false);
1682 if (ret == e_success) { 1724 if (ret == e_success) {
1683 break; 1725 break;
1684 } else if (ret == e_wrongPw) { 1726 } else if (ret == e_wrongPw) {
1685 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1727 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1686 } else { 1728 } else {
1687 printDebug("deep-unlocking failed while " 1729 printDebug("deep-unlocking failed while "
1688 "tempoary unlocking!"); 1730 "tempoary unlocking!");
1689 return false; 1731 return false;
1690 } 1732 }
1691 } 1733 }
1692 wasDeepLocked = true; 1734 wasDeepLocked = true;
1693 mustUnlock = true; 1735 mustUnlock = true;
1694 } else { 1736 } else {
1695 // first check if it's needed to unlock some entries 1737 // first check if it's needed to unlock some entries
1696 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1738 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1697 catEnd = dti.dta.end(), 1739 catEnd = dti.dta.end(),
1698 catI = catBegin; 1740 catI = catBegin;
1699 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1741 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1700 while (catI != catEnd) { 1742 while (catI != catEnd) {
1701 entrBegin = catI->d.begin(); 1743 entrBegin = catI->d.begin();
1702 entrEnd = catI->d.end(); 1744 entrEnd = catI->d.end();
1703 entrI = entrBegin; 1745 entrI = entrBegin;
1704 while (entrI != entrEnd) { 1746 while (entrI != entrEnd) {
1705 if (entrI->lockStat == true) { 1747 if (entrI->lockStat == true) {
1706 mustUnlock = true; 1748 mustUnlock = true;
1707 break; 1749 break;
1708 } 1750 }
1709 ++entrI; 1751 ++entrI;
1710 } 1752 }
1711 if (mustUnlock) 1753 if (mustUnlock)
1712 break; 1754 break;
1713 ++catI; 1755 ++catI;
1714 } 1756 }
1715 } 1757 }
1716 if (!mustUnlock) { 1758 if (!mustUnlock) {
1717 // nothing to do. 1759 // nothing to do.
1718 timer()->stop(DocTimer::id_autoLockTimer); 1760 timer()->stop(DocTimer::id_autoLockTimer);
1719 printDebug("unlockAll_tempoary(): nothing to do."); 1761 printDebug("unlockAll_tempoary(): nothing to do.");
1720 return true; 1762 return true;
1721 } else if (!wasDeepLocked) { 1763 } else if (!wasDeepLocked) {
1722 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && 1764 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) &&
1723 currentPw != "") { 1765 currentPw != "") {
1724 /* we can't unlock without mpw, so 1766 /* we can't unlock without mpw, so
1725 * we need to ask for it. 1767 * we need to ask for it.
1726 */ 1768 */
1727 QString pw; 1769 QString pw;
1728 while (1) { 1770 while (1) {
1729 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1771 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1730 if (pw == "") { 1772 if (pw == "") {
1731 return false; 1773 return false;
1732 } else if (pw == currentPw) { 1774 } else if (pw == currentPw) {
1733 break; 1775 break;
1734 } 1776 }
1735 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1777 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1736 } 1778 }
1737 } 1779 }
1738 } 1780 }
1739 timer()->stop(DocTimer::id_autoLockTimer); 1781 timer()->stop(DocTimer::id_autoLockTimer);
1740 oldLockStates = new vector< vector<bool> >; 1782 oldLockStates = new vector< vector<bool> >;
1741 vector<bool> tmp_vec; 1783 vector<bool> tmp_vec;
1742 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1784 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1743 catEnd = dti.dta.end(), 1785 catEnd = dti.dta.end(),
1744 catI = catBegin; 1786 catI = catBegin;
1745 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1787 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1746 while (catI != catEnd) { 1788 while (catI != catEnd) {
1747 entrBegin = catI->d.begin(); 1789 entrBegin = catI->d.begin();
1748 entrEnd = catI->d.end(); 1790 entrEnd = catI->d.end();
1749 entrI = entrBegin; 1791 entrI = entrBegin;
1750 while (entrI != entrEnd) { 1792 while (entrI != entrEnd) {
1751 if (!wasDeepLocked) { 1793 if (!wasDeepLocked) {
1752 tmp_vec.push_back(entrI->lockStat); 1794 tmp_vec.push_back(entrI->lockStat);
1753 } 1795 }
1754 entrI->lockStat = false; 1796 entrI->lockStat = false;
1755 ++entrI; 1797 ++entrI;
1756 } 1798 }
1757 if (!wasDeepLocked) { 1799 if (!wasDeepLocked) {
1758 oldLockStates->push_back(tmp_vec); 1800 oldLockStates->push_back(tmp_vec);
1759 tmp_vec.clear(); 1801 tmp_vec.clear();
1760 } 1802 }
1761 ++catI; 1803 ++catI;
1762 } 1804 }
1763 printDebug("tempoary unlocked dta."); 1805 printDebug("tempoary unlocked dta.");
1764 } 1806 }
1765 1807
1766 return true; 1808 return true;
1767} 1809}
1768 1810
1769PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) 1811PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
1770{ 1812{
1771 PwMerror ret; 1813 PwMerror ret;
1814 /* NOTE: saveDoc() depends on this function to return
1815 * e_success if saveToFile == false
1816 */
1772 1817
1773 if (lock) { 1818 if (lock) {
1774 if (isDeepLocked()) 1819 if (isDeepLocked())
1775 return e_lock; 1820 return e_lock;
1776 if (saveToFile) { 1821 if (saveToFile) {
1777 if (isDocEmpty()) 1822 if (isDocEmpty())
1778 return e_docIsEmpty; 1823 return e_docIsEmpty;
1779 ret = saveDoc(conf()->confGlobCompression()); 1824 ret = saveDoc(conf()->confGlobCompression());
1780 if (ret == e_filename) { 1825 if (ret == e_filename) {
1781 /* the doc wasn't saved to a file 1826 /* the doc wasn't saved to a file
1782 * by the user, yet. 1827 * by the user, yet.
1783 */ 1828 */
1784 cantDeeplock_notSavedMsgBox(); 1829 cantDeeplock_notSavedMsgBox();
1785 return e_docNotSaved; 1830 return e_docNotSaved;
1786 } else if (ret != e_success) { 1831 } else if (ret != e_success) {
1787 return e_lock; 1832 return e_lock;
1788 } 1833 }
1789 } 1834 }
1790 timer()->stop(DocTimer::id_autoLockTimer); 1835 timer()->stop(DocTimer::id_autoLockTimer);
1791 clearDoc(); 1836 clearDoc();
1792 PwMDataItem d; 1837 PwMDataItem d;
1793 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); 1838 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
1794 d.comment = IS_DEEPLOCKED_MSG.latin1(); 1839 d.comment = IS_DEEPLOCKED_MSG.latin1();
1795 d.listViewPos = 0; 1840 d.listViewPos = 0;
1796 addEntry(DEFAULT_CATEGORY, &d, true); 1841 addEntry(DEFAULT_CATEGORY, &d, true);
1797 lockAt(DEFAULT_CATEGORY, 0, true); 1842 lockAt(DEFAULT_CATEGORY, 0, true);
1798 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 1843 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
1799 setDocStatFlag(DOC_STAT_DEEPLOCKED); 1844 setDocStatFlag(DOC_STAT_DEEPLOCKED);
1800 } else { 1845 } else {
1801 if (!isDeepLocked()) 1846 if (!isDeepLocked())
1802 return e_lock; 1847 return e_lock;
1803 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) 1848 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
1804 ? 0 : 1); 1849 ? 0 : 1);
1805 if (ret == e_wrongPw) { 1850 if (ret == e_wrongPw) {
1806 return e_wrongPw; 1851 return e_wrongPw;
1807 } else if (ret != e_success) { 1852 } else if (ret != e_success) {
1808 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") 1853 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
1809 + tostr(static_cast<int>(ret))); 1854 + tostr(static_cast<int>(ret)));
1810 return e_lock; 1855 return e_lock;
1811 } 1856 }
1812 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1857 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1813 timer()->start(DocTimer::id_autoLockTimer); 1858 timer()->start(DocTimer::id_autoLockTimer);
1814 } 1859 }
1815 1860
1816 emitDataChanged(this); 1861 emitDataChanged(this);
1817 return e_success; 1862 return e_success;
1818} 1863}
1819 1864
1820void PwMDoc::_deepUnlock() 1865void PwMDoc::_deepUnlock()
1821{ 1866{
1822 deepLock(false); 1867 deepLock(false);
1823} 1868}
1824 1869
1825void PwMDoc::clearDoc() 1870void PwMDoc::clearDoc()
1826{ 1871{
1827 dti.clear(); 1872 dti.clear();
1828 PwMCategoryItem d; 1873 PwMCategoryItem d;
1829 d.name = DEFAULT_CATEGORY.latin1(); 1874 d.name = DEFAULT_CATEGORY.latin1();
1830 dti.dta.push_back(d); 1875 dti.dta.push_back(d);
1831 currentPw = ""; 1876 currentPw = "";
1832 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 1877 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
1833} 1878}
1834 1879
1835void PwMDoc::changeCurrentPw() 1880void PwMDoc::changeCurrentPw()
1836{ 1881{
1837 if (currentPw == "") 1882 if (currentPw == "")
1838 return; // doc hasn't been saved. No mpw available. 1883 return; // doc hasn't been saved. No mpw available.
1839 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 1884 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
1840 QString pw = requestMpwChange(&currentPw, &useChipcard); 1885 QString pw = requestMpwChange(&currentPw, &useChipcard);
1841 if (pw == "") 1886 if (pw == "")
1842 return; 1887 return;
1843 if (useChipcard) 1888 if (useChipcard)
1844 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 1889 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
1845 else 1890 else
1846 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 1891 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
1847 setCurrentPw(pw); 1892 setCurrentPw(pw);
1848} 1893}
1849 1894
1850void PwMDoc::setListViewPos(const QString &category, unsigned int index, 1895void PwMDoc::setListViewPos(const QString &category, unsigned int index,
1851 int pos) 1896 int pos)
1852{ 1897{
1853 unsigned int cat = 0; 1898 unsigned int cat = 0;
1854 1899
1855 if (!findCategory(category, &cat)) { 1900 if (!findCategory(category, &cat)) {
1856 BUG(); 1901 BUG();
1857 return; 1902 return;
1858 } 1903 }
1859 setListViewPos(cat, index, pos); 1904 setListViewPos(cat, index, pos);
1860} 1905}
1861 1906
1862void PwMDoc::setListViewPos(unsigned int category, unsigned int index, 1907void PwMDoc::setListViewPos(unsigned int category, unsigned int index,
1863 int pos) 1908 int pos)
1864{ 1909{
1865 dti.dta[category].d[index].listViewPos = pos; 1910 dti.dta[category].d[index].listViewPos = pos;
1866 1911
1867/* FIXME workaround: don't flag dirty, because this function sometimes 1912/* FIXME workaround: don't flag dirty, because this function sometimes
1868 * get's called when it shouldn't. It's because PwMView assumes 1913 * get's called when it shouldn't. It's because PwMView assumes
1869 * the user resorted the UI on behalf of signal layoutChanged(). 1914 * the user resorted the UI on behalf of signal layoutChanged().
1870 * This is somewhat broken and incorrect, but I've no other 1915 * This is somewhat broken and incorrect, but I've no other
1871 * solution for now. 1916 * solution for now.
1872 */ 1917 */
1873 //setDocStatFlag(DOC_STAT_DISK_DIRTY); 1918 //setDocStatFlag(DOC_STAT_DISK_DIRTY);
1874} 1919}
1875 1920
1876int PwMDoc::getListViewPos(const QString &category, unsigned int index) 1921int PwMDoc::getListViewPos(const QString &category, unsigned int index)
1877{ 1922{
1878 unsigned int cat = 0; 1923 unsigned int cat = 0;
1879 1924
1880 if (!findCategory(category, &cat)) { 1925 if (!findCategory(category, &cat)) {
1881 BUG(); 1926 BUG();
1882 return -1; 1927 return -1;
1883 } 1928 }
1884 1929
1885 return dti.dta[cat].d[index].listViewPos; 1930 return dti.dta[cat].d[index].listViewPos;
1886} 1931}
1887 1932
1888void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, 1933void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
1889 vector<unsigned int> *foundPositions, bool breakAfterFound, 1934 vector<unsigned int> *foundPositions, bool breakAfterFound,
1890 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 1935 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
1891{ 1936{
1892 PWM_ASSERT(foundPositions); 1937 PWM_ASSERT(foundPositions);
1893 PWM_ASSERT(searchIn); 1938 PWM_ASSERT(searchIn);
1894 foundPositions->clear(); 1939 foundPositions->clear();
1895 1940
1896 unsigned int i, entries = numEntries(category); 1941 unsigned int i, entries = numEntries(category);
1897 for (i = 0; i < entries; ++i) { 1942 for (i = 0; i < entries; ++i) {
1898 if (searchIn & SEARCH_IN_DESC) { 1943 if (searchIn & SEARCH_IN_DESC) {
1899 if (!compareString(find.desc, dti.dta[category].d[i].desc, 1944 if (!compareString(find.desc, dti.dta[category].d[i].desc,
1900 caseSensitive, exactWordMatch)) { 1945 caseSensitive, exactWordMatch)) {
1901 continue; 1946 continue;
1902 } 1947 }
1903 } 1948 }
1904 if (searchIn & SEARCH_IN_NAME) { 1949 if (searchIn & SEARCH_IN_NAME) {
1905 if (!compareString(find.name, dti.dta[category].d[i].name, 1950 if (!compareString(find.name, dti.dta[category].d[i].name,
1906 caseSensitive, exactWordMatch)) { 1951 caseSensitive, exactWordMatch)) {
1907 continue; 1952 continue;
1908 } 1953 }
1909 } 1954 }
1910 if (searchIn & SEARCH_IN_PW) { 1955 if (searchIn & SEARCH_IN_PW) {
1911 bool wasLocked = isLocked(category, i); 1956 bool wasLocked = isLocked(category, i);
1912 getDataChangedLock(); 1957 getDataChangedLock();
1913 lockAt(category, i, false); 1958 lockAt(category, i, false);
1914 if (!compareString(find.pw, dti.dta[category].d[i].pw, 1959 if (!compareString(find.pw, dti.dta[category].d[i].pw,
1915 caseSensitive, exactWordMatch)) { 1960 caseSensitive, exactWordMatch)) {
1916 lockAt(category, i, wasLocked); 1961 lockAt(category, i, wasLocked);
1917 putDataChangedLock(); 1962 putDataChangedLock();
1918 continue; 1963 continue;
1919 } 1964 }
1920 lockAt(category, i, wasLocked); 1965 lockAt(category, i, wasLocked);
1921 putDataChangedLock(); 1966 putDataChangedLock();
1922 } 1967 }
1923 if (searchIn & SEARCH_IN_COMMENT) { 1968 if (searchIn & SEARCH_IN_COMMENT) {
1924 if (!compareString(find.comment, dti.dta[category].d[i].comment, 1969 if (!compareString(find.comment, dti.dta[category].d[i].comment,
1925 caseSensitive, exactWordMatch)) { 1970 caseSensitive, exactWordMatch)) {
1926 continue; 1971 continue;
1927 } 1972 }
1928 } 1973 }
1929 if (searchIn & SEARCH_IN_URL) { 1974 if (searchIn & SEARCH_IN_URL) {
1930 if (!compareString(find.url, dti.dta[category].d[i].url, 1975 if (!compareString(find.url, dti.dta[category].d[i].url,
1931 caseSensitive, exactWordMatch)) { 1976 caseSensitive, exactWordMatch)) {
1932 continue; 1977 continue;
1933 } 1978 }
1934 } 1979 }
1935 if (searchIn & SEARCH_IN_LAUNCHER) { 1980 if (searchIn & SEARCH_IN_LAUNCHER) {
1936 if (!compareString(find.launcher, dti.dta[category].d[i].launcher, 1981 if (!compareString(find.launcher, dti.dta[category].d[i].launcher,
1937 caseSensitive, exactWordMatch)) { 1982 caseSensitive, exactWordMatch)) {
1938 continue; 1983 continue;
1939 } 1984 }
1940 } 1985 }
1941 1986
1942 // all selected "searchIn" matched. 1987 // all selected "searchIn" matched.
1943 foundPositions->push_back(i); 1988 foundPositions->push_back(i);
1944 if (breakAfterFound) 1989 if (breakAfterFound)
1945 break; 1990 break;
1946 } 1991 }
1947 1992
1948 if (sortByLvp && foundPositions->size() > 1) { 1993 if (sortByLvp && foundPositions->size() > 1) {
1949 vector< pair<unsigned int /* foundPosition (real doc pos) */, 1994 vector< pair<unsigned int /* foundPosition (real doc pos) */,
1950 unsigned int /* lvp-pos */> > tmp_vec; 1995 unsigned int /* lvp-pos */> > tmp_vec;
1951 1996
1952 unsigned int i, items = foundPositions->size(); 1997 unsigned int i, items = foundPositions->size();
1953 pair<unsigned int, unsigned int> tmp_pair; 1998 pair<unsigned int, unsigned int> tmp_pair;
1954 for (i = 0; i < items; ++i) { 1999 for (i = 0; i < items; ++i) {
1955 tmp_pair.first = (*foundPositions)[i]; 2000 tmp_pair.first = (*foundPositions)[i];
1956 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; 2001 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos;
1957 tmp_vec.push_back(tmp_pair); 2002 tmp_vec.push_back(tmp_pair);
1958 } 2003 }
1959 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); 2004 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater());
1960 foundPositions->clear(); 2005 foundPositions->clear();
1961 for (i = 0; i < items; ++i) { 2006 for (i = 0; i < items; ++i) {
1962 foundPositions->push_back(tmp_vec[i].first); 2007 foundPositions->push_back(tmp_vec[i].first);
1963 } 2008 }
1964 } 2009 }
1965} 2010}
1966 2011
1967void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, 2012void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
1968 vector<unsigned int> *foundPositions, bool breakAfterFound, 2013 vector<unsigned int> *foundPositions, bool breakAfterFound,
1969 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 2014 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
1970{ 2015{
1971 PWM_ASSERT(foundPositions); 2016 PWM_ASSERT(foundPositions);
1972 unsigned int cat = 0; 2017 unsigned int cat = 0;
1973 2018
1974 if (!findCategory(category, &cat)) { 2019 if (!findCategory(category, &cat)) {
1975 foundPositions->clear(); 2020 foundPositions->clear();
1976 return; 2021 return;
1977 } 2022 }
1978 2023
1979 findEntry(cat, find, searchIn, foundPositions, breakAfterFound, 2024 findEntry(cat, find, searchIn, foundPositions, breakAfterFound,
1980 caseSensitive, exactWordMatch, sortByLvp); 2025 caseSensitive, exactWordMatch, sortByLvp);
1981} 2026}
1982 2027
1983bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, 2028bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive,
1984 bool exactWordMatch) 2029 bool exactWordMatch)
1985{ 2030{
1986 QString _s1(s1.c_str()); 2031 QString _s1(s1.c_str());
1987 QString _s2(s2.c_str()); 2032 QString _s2(s2.c_str());
1988 if (!caseSensitive) { 2033 if (!caseSensitive) {
1989 _s1 = _s1.lower(); 2034 _s1 = _s1.lower();
1990 _s2 = _s2.lower(); 2035 _s2 = _s2.lower();
1991 } 2036 }
1992 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) 2037 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1))
1993 return true; 2038 return true;
1994 return false; 2039 return false;
1995} 2040}
1996 2041
1997bool PwMDoc::findCategory(const QString &name, unsigned int *index) 2042bool PwMDoc::findCategory(const QString &name, unsigned int *index)
1998{ 2043{
1999 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2044 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2000 end = dti.dta.end(); 2045 end = dti.dta.end();
2001 while (i != end) { 2046 while (i != end) {
2002 if ((*i).name == name.latin1()) { 2047 if ((*i).name == name.latin1()) {
2003 if (index) { 2048 if (index) {
2004 *index = i - dti.dta.begin(); 2049 *index = i - dti.dta.begin();
2005 } 2050 }
2006 return true; 2051 return true;
2007 } 2052 }
2008 ++i; 2053 ++i;
2009 } 2054 }
2010 return false; 2055 return false;
2011} 2056}
2012 2057
2013bool PwMDoc::renameCategory(const QString &category, const QString &newName) 2058bool PwMDoc::renameCategory(const QString &category, const QString &newName)
2014{ 2059{
2015 unsigned int cat = 0; 2060 unsigned int cat = 0;
2016 2061
2017 if (!findCategory(category, &cat)) 2062 if (!findCategory(category, &cat))
2018 return false; 2063 return false;
2019 2064
2020 return renameCategory(cat, newName); 2065 return renameCategory(cat, newName);
2021} 2066}
2022 2067
2023bool PwMDoc::renameCategory(unsigned int category, const QString &newName, 2068bool PwMDoc::renameCategory(unsigned int category, const QString &newName,
2024 bool dontFlagDirty) 2069 bool dontFlagDirty)
2025{ 2070{
2026 if (category > numCategories() - 1) 2071 if (category > numCategories() - 1)
2027 return false; 2072 return false;
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 535fb92..a6e5f58 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -1,270 +1,270 @@
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 2.0 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#ifndef __PWMDOC_H 20#ifndef __PWMDOC_H
21#define __PWMDOC_H 21#define __PWMDOC_H
22 22
23 #define PWM_FILE_VER (static_cast<char>(0x05)) 23 #define PWM_FILE_VER (static_cast<char>(0x05))
24 24
25 #define PWM_HASH_SHA1 (static_cast<char>(0x01)) 25 #define PWM_HASH_SHA1 (static_cast<char>(0x01))
26 #define PWM_HASH_SHA256 (static_cast<char>(0x02)) 26 #define PWM_HASH_SHA256 (static_cast<char>(0x02))
27 #define PWM_HASH_SHA384 (static_cast<char>(0x03)) 27 #define PWM_HASH_SHA384 (static_cast<char>(0x03))
28 #define PWM_HASH_SHA512 (static_cast<char>(0x04)) 28 #define PWM_HASH_SHA512 (static_cast<char>(0x04))
29 #define PWM_HASH_MD5 (static_cast<char>(0x05)) 29 #define PWM_HASH_MD5 (static_cast<char>(0x05))
30 #define PWM_HASH_RMD160 (static_cast<char>(0x06)) 30 #define PWM_HASH_RMD160 (static_cast<char>(0x06))
31 #define PWM_HASH_TIGER (static_cast<char>(0x07)) 31 #define PWM_HASH_TIGER (static_cast<char>(0x07))
32 32
33 #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01)) 33 #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01))
34 #define PWM_CRYPT_AES128(static_cast<char>(0x02)) 34 #define PWM_CRYPT_AES128(static_cast<char>(0x02))
35 #define PWM_CRYPT_AES192(static_cast<char>(0x03)) 35 #define PWM_CRYPT_AES192(static_cast<char>(0x03))
36 #define PWM_CRYPT_AES256(static_cast<char>(0x04)) 36 #define PWM_CRYPT_AES256(static_cast<char>(0x04))
37 #define PWM_CRYPT_3DES (static_cast<char>(0x05)) 37 #define PWM_CRYPT_3DES (static_cast<char>(0x05))
38 #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06)) 38 #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06))
39 #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07)) 39 #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07))
40 40
41 #define PWM_COMPRESS_NONE(static_cast<char>(0x00)) 41 #define PWM_COMPRESS_NONE(static_cast<char>(0x00))
42 #define PWM_COMPRESS_GZIP(static_cast<char>(0x01)) 42 #define PWM_COMPRESS_GZIP(static_cast<char>(0x01))
43 #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02)) 43 #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02))
44 44
45 #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0))) 45 #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0)))
46 #define FILE_ID_HEADER "PWM_PASSWORD_FILE" 46 #define FILE_ID_HEADER "PWM_PASSWORD_FILE"
47 47
48 48
49#include "pwmexception.h" 49#include "pwmexception.h"
50#include "pwmdocui.h" 50#include "pwmdocui.h"
51 51
52#include <qobject.h> 52#include <qobject.h>
53#include <qtimer.h> 53#include <qtimer.h>
54#include <qdatetime.h> 54#include <qdatetime.h>
55 55
56#include <kprocess.h> 56#include <kprocess.h>
57 57
58#ifndef PWM_EMBEDDED 58#ifndef PWM_EMBEDDED
59#include "configuration.h" 59#include "configuration.h"
60#else 60#else
61#include <kapplication.h> 61#include <kapplication.h>
62#include <ksyncmanager.h> 62#include <ksyncmanager.h>
63#endif 63#endif
64 64
65#include <string> 65#include <string>
66#include <vector> 66#include <vector>
67#include <utility> 67#include <utility>
68 68
69using std::vector; 69using std::vector;
70using std::string; 70using std::string;
71using std::pair; 71using std::pair;
72 72
73/* used in findEntry() function */ 73/* used in findEntry() function */
74 #define SEARCH_IN_DESC (1) 74 #define SEARCH_IN_DESC (1)
75 #define SEARCH_IN_NAME (1 << 1) 75 #define SEARCH_IN_NAME (1 << 1)
76 #define SEARCH_IN_PW (1 << 2) 76 #define SEARCH_IN_PW (1 << 2)
77 #define SEARCH_IN_COMMENT(1 << 3) 77 #define SEARCH_IN_COMMENT(1 << 3)
78 #define SEARCH_IN_URL (1 << 4) 78 #define SEARCH_IN_URL (1 << 4)
79 #define SEARCH_IN_LAUNCHER(1 << 5) 79 #define SEARCH_IN_LAUNCHER(1 << 5)
80 #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \ 80 #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \
81 SEARCH_IN_PW | SEARCH_IN_COMMENT| \ 81 SEARCH_IN_PW | SEARCH_IN_COMMENT| \
82 SEARCH_IN_URL| SEARCH_IN_LAUNCHER) 82 SEARCH_IN_URL| SEARCH_IN_LAUNCHER)
83 83
84/** document deeplocked. Data is out for lunch to disk */ 84/** document deeplocked. Data is out for lunch to disk */
85 #define DOC_STAT_DEEPLOCKED (1) 85 #define DOC_STAT_DEEPLOCKED (1)
86/** encrypted document on disk is dirty. data has to go to disk. */ 86/** encrypted document on disk is dirty. data has to go to disk. */
87 #define DOC_STAT_DISK_DIRTY (1 << 1) 87 #define DOC_STAT_DISK_DIRTY (1 << 1)
88/** we are using a chipcard to encrypt the data */ 88/** we are using a chipcard to encrypt the data */
89 #define DOC_STAT_USE_CHIPCARD (1 << 2) 89 #define DOC_STAT_USE_CHIPCARD (1 << 2)
90/** use "currentPw" to unlock. (This flag is set/unset by a timer) */ 90/** use "currentPw" to unlock. (This flag is set/unset by a timer) */
91 #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3) 91 #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3)
92 92
93class PwMDoc; 93class PwMDoc;
94class PwMView; 94class PwMView;
95class QFile; 95class QFile;
96 96
97/* meta data for a PwMDataItem */ 97/* meta data for a PwMDataItem */
98struct PwMMetaData 98struct PwMMetaData
99{ 99{
100 PwMMetaData() 100 PwMMetaData()
101 : updateInt (0) 101 : updateInt (0)
102 { } 102 { }
103 /** creation date of the PwMDataItem to which 103 /** creation date of the PwMDataItem to which
104 * this meta data belongs. 104 * this meta data belongs.
105 */ 105 */
106 QDateTimecreate; 106 QDateTimecreate;
107 /** becomes valid on this date */ 107 /** becomes valid on this date */
108 QDateTimevalid; 108 QDateTimevalid;
109 /** expire date */ 109 /** expire date */
110 QDateTimeexpire; 110 QDateTimeexpire;
111 /** update date (last updated at this date) */ 111 /** update date (last updated at this date) */
112 QDateTimeupdate; 112 QDateTimeupdate;
113 /** update interval (in minutes). Time since the 113 /** update interval (in minutes). Time since the
114 * last update to remind the user to update the item. 114 * last update to remind the user to update the item.
115 * 0 disables. 115 * 0 disables.
116 */ 116 */
117 unsigned long updateInt; 117 unsigned long updateInt;
118 118
119 //US ENH: enhancements of the filestructure 119 //US ENH: enhancements of the filestructure
120 /* each entry gets a unique id assigned */ 120 /* each entry gets a unique id assigned */
121 string uniqueid; 121 string uniqueid;
122 122
123 123
124 void clear() 124 void clear()
125 { 125 {
126 create = QDateTime(); 126 create = QDateTime();
127 expire = QDateTime(); 127 expire = QDateTime();
128 update = QDateTime(); 128 update = QDateTime();
129 updateInt = 0; 129 updateInt = 0;
130 uniqueid = KApplication::randomString(8); 130 uniqueid = KApplication::randomString(8);
131 } 131 }
132 132
133 inline bool isValid() const 133 inline bool isValid() const
134 { 134 {
135 if (valid.isNull()) 135 if (valid.isNull())
136 return true; 136 return true;
137 return (valid < QDateTime::currentDateTime()); 137 return (valid < QDateTime::currentDateTime());
138 } 138 }
139 inline bool isExpired() const 139 inline bool isExpired() const
140 { 140 {
141 if (expire.isNull()) 141 if (expire.isNull())
142 return false; 142 return false;
143 return (expire < QDateTime::currentDateTime()); 143 return (expire < QDateTime::currentDateTime());
144 } 144 }
145 inline bool isUpdateIntOver() const 145 inline bool isUpdateIntOver() const
146 { 146 {
147 if (updateInt == 0 || 147 if (updateInt == 0 ||
148 update.isNull()) 148 update.isNull())
149 return false; 149 return false;
150 QDateTime d(update); 150 QDateTime d(update);
151 return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); 151 return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime());
152 } 152 }
153}; 153};
154 154
155struct PwMDataItem 155struct PwMDataItem
156{ 156{
157 PwMDataItem() 157 PwMDataItem()
158 : lockStat (true) 158 : lockStat (true)
159 , listViewPos (-1) 159 , listViewPos (-1)
160 , binary (false) 160 , binary (false)
161 , rev (0) 161 , rev (0)
162 { } 162 { }
163 163
164 /** password description */ 164 /** password description */
165 stringdesc; 165 stringdesc;
166 /** user-name */ 166 /** user-name */
167 stringname; 167 stringname;
168 /** the password itself */ 168 /** the password itself */
169 stringpw; 169 stringpw;
170 /** some comment */ 170 /** some comment */
171 stringcomment; 171 stringcomment;
172 /** an URL string */ 172 /** an URL string */
173 stringurl; 173 stringurl;
174 /** launcher. Can be executed as a system() command */ 174 /** launcher. Can be executed as a system() command */
175 stringlauncher; 175 stringlauncher;
176 /** locking status. If locked (true), pw is not emitted through getEntry() */ 176 /** locking status. If locked (true), pw is not emitted through getEntry() */
177 boollockStat; 177 boollockStat;
178 /** position of this item in main "list-view" 178 /** position of this item in main "list-view"
179 * If -1, the position is not yet specified and should be appended to the list 179 * If -1, the position is not yet specified and should be appended to the list
180 */ 180 */
181 intlistViewPos; 181 intlistViewPos;
182 /** does this entry contain binary data? */ 182 /** does this entry contain binary data? */
183 bool binary; 183 bool binary;
184 /** meta data for this data item. */ 184 /** meta data for this data item. */
185 PwMMetaData meta; 185 PwMMetaData meta;
186 /** data revision counter. This counter can be used 186 /** data revision counter. This counter can be used
187 * to easily, efficiently determine if this data item 187 * to easily, efficiently determine if this data item
188 * has changed since some time. 188 * has changed since some time.
189 * This counter is incremented on every update. 189 * This counter is incremented on every update.
190 */ 190 */
191 unsigned int rev; 191 unsigned int rev;
192 192
193 void clear(bool clearMeta = true) 193 void clear(bool clearMeta = true)
194 { 194 {
195 /* NOTE: Don't use .clear() here to be 195 /* NOTE: Don't use .clear() here to be
196 * backward compatible with gcc-2 (Debian Woody) 196 * backward compatible with gcc-2 (Debian Woody)
197 */ 197 */
198 desc = ""; 198 desc = "";
199 name = ""; 199 name = "";
200 pw = ""; 200 pw = "";
201 comment = ""; 201 comment = "";
202 url = ""; 202 url = "";
203 launcher = ""; 203 launcher = "";
204 lockStat = true; 204 lockStat = true;
205 listViewPos = -1; 205 listViewPos = -1;
206 binary = false; 206 binary = false;
207 if (clearMeta) 207 if (clearMeta)
208 meta.clear(); 208 meta.clear();
209 } 209 }
210 //US ENH: we need this operator to compare two items if we have no unique ids 210 //US ENH: we need this operator to compare two items if we have no unique ids
211 //available. Generaly this happens before the first sync 211 //available. Generaly this happens before the first sync
212 212
213 bool PwMDataItem::operator==( const PwMDataItem &a ) const 213 bool PwMDataItem::operator==( const PwMDataItem &a ) const
214 { 214 {
215 //qDebug("oper==%s", a.desc.c_str()); 215 //qDebug("oper==%s", a.desc.c_str());
216 if ( desc != a.desc ) return false; 216 if ( desc != a.desc ) return false;
217 if ( name != a.name ) return false; 217 if ( name != a.name ) return false;
218 if ( pw != a.pw ) return false; 218 if ( pw != a.pw ) return false;
219 if ( comment != a.comment ) return false; 219 if ( comment != a.comment ) return false;
220 if ( url != a.url ) return false; 220 if ( url != a.url ) return false;
221 if ( launcher != a.launcher ) return false; 221 if ( launcher != a.launcher ) return false;
222 //all other field will not be checked. 222 //all other field will not be checked.
223 return true; 223 return true;
224 } 224 }
225}; 225};
226 226
227struct PwMCategoryItem 227struct PwMCategoryItem
228{ 228{
229 /** all PwMDataItems (all passwords) within this category */ 229 /** all PwMDataItems (all passwords) within this category */
230 vector<PwMDataItem>d; 230 vector<PwMDataItem>d;
231 /** category name/description */ 231 /** category name/description */
232 string name; 232 string name;
233 233
234 void clear() 234 void clear()
235 { 235 {
236 d.clear(); 236 d.clear();
237 name = ""; 237 name = "";
238 } 238 }
239}; 239};
240 240
241struct PwMSyncItem 241struct PwMSyncItem
242{ 242{
243 string syncName; 243 string syncName;
244 QDateTime lastSyncDate; 244 QDateTime lastSyncDate;
245 245
246 void clear() 246 void clear()
247 { 247 {
248 lastSyncDate = QDateTime(); 248 lastSyncDate = QDateTime();
249 syncName = ""; 249 syncName = "";
250 } 250 }
251}; 251};
252 252
253struct PwMItem 253struct PwMItem
254{ 254{
255 vector<PwMCategoryItem> dta; 255 vector<PwMCategoryItem> dta;
256 vector<PwMSyncItem> syncDta; 256 vector<PwMSyncItem> syncDta;
257 257
258 void clear() 258 void clear()
259 { 259 {
260 dta.clear(); 260 dta.clear();
261 syncDta.clear(); 261 syncDta.clear();
262 } 262 }
263}; 263};
264 264
265 265
266/** "Function Object" for sort()ing PwMDataItem::listViewPos */ 266/** "Function Object" for sort()ing PwMDataItem::listViewPos */
267class dta_lvp_greater 267class dta_lvp_greater
268{ 268{
269public: 269public:
270 bool operator() (const pair<unsigned int, unsigned int> &d1, 270 bool operator() (const pair<unsigned int, unsigned int> &d1,
diff --git a/pwmanager/pwmanager/pwmdocui.cpp b/pwmanager/pwmanager/pwmdocui.cpp
index 7b8e0ee..6ddb6f5 100644
--- a/pwmanager/pwmanager/pwmdocui.cpp
+++ b/pwmanager/pwmanager/pwmdocui.cpp
@@ -20,438 +20,448 @@
20#include "pwmdocui.h" 20#include "pwmdocui.h"
21#include "setmasterpwwndimpl.h" 21#include "setmasterpwwndimpl.h"
22#include "getmasterpwwndimpl.h" 22#include "getmasterpwwndimpl.h"
23#include "pwmexception.h" 23#include "pwmexception.h"
24#include "getkeycardwnd.h" 24#include "getkeycardwnd.h"
25#include "pwm.h" 25#include "pwm.h"
26#include "globalstuff.h" 26#include "globalstuff.h"
27#include "spinforsignal.h" 27#include "spinforsignal.h"
28 28
29#include <qlineedit.h> 29#include <qlineedit.h>
30#include <qtabwidget.h> 30#include <qtabwidget.h>
31 31
32#include <kmessagebox.h> 32#include <kmessagebox.h>
33#include <kfiledialog.h> 33#include <kfiledialog.h>
34 34
35#ifndef PWM_EMBEDDED 35#ifndef PWM_EMBEDDED
36#include <kwin.h> 36#include <kwin.h>
37#else 37#else
38#include <qdir.h> 38#include <qdir.h>
39#include "pwmprefs.h" 39#include "pwmprefs.h"
40#endif 40#endif
41 41
42 42
43#ifdef CONFIG_KEYCARD 43#ifdef CONFIG_KEYCARD
44# include "pwmkeycard.h" 44# include "pwmkeycard.h"
45#endif 45#endif
46 46
47 47
48PwMDocUi::PwMDocUi(QObject *parent, const char *name) 48PwMDocUi::PwMDocUi(QObject *parent, const char *name)
49 : QObject(parent, name) 49 : QObject(parent, name)
50{ 50{
51 currentView = 0; 51 currentView = 0;
52 keyCard = 0; 52 keyCard = 0;
53} 53}
54 54
55PwMDocUi::~PwMDocUi() 55PwMDocUi::~PwMDocUi()
56{ 56{
57} 57}
58 58
59QString PwMDocUi::requestMpw(bool chipcard) 59QString PwMDocUi::requestMpw(bool chipcard)
60{ 60{
61 QString pw; 61 QString pw;
62 62
63 if (chipcard) { 63 if (chipcard) {
64#ifdef CONFIG_KEYCARD 64#ifdef CONFIG_KEYCARD
65 PWM_ASSERT(keyCard); 65 PWM_ASSERT(keyCard);
66 uint32_t id; 66 uint32_t id;
67 string ret; 67 string ret;
68 SpinForSignal *spinner = keyCard->getSpinner(); 68 SpinForSignal *spinner = keyCard->getSpinner();
69 connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), 69 connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)),
70 spinner, SLOT(u32_str_slot(uint32_t, const string &))); 70 spinner, SLOT(u32_str_slot(uint32_t, const string &)));
71 keyCard->getKey(); 71 keyCard->getKey();
72 spinner->spin(&id, &ret); 72 spinner->spin(&id, &ret);
73 disconnect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), 73 disconnect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)),
74 spinner, SLOT(u32_str_slot(uint32_t, const string &))); 74 spinner, SLOT(u32_str_slot(uint32_t, const string &)));
75 if (ret == "") 75 if (ret == "")
76 return ""; 76 return "";
77 pw = ret.c_str(); 77 pw = ret.c_str();
78#else // CONFIG_KEYCARD 78#else // CONFIG_KEYCARD
79 no_keycard_support_msg_box(currentView); 79 no_keycard_support_msg_box(currentView);
80#endif // CONFIG_KEYCARD 80#endif // CONFIG_KEYCARD
81 } else { 81 } else {
82#ifndef PWM_EMBEDDED 82#ifndef PWM_EMBEDDED
83 GetMasterPwWndImpl pwWnd; 83 GetMasterPwWndImpl pwWnd;
84 KWin::setState(pwWnd.winId(), NET::StaysOnTop); 84 KWin::setState(pwWnd.winId(), NET::StaysOnTop);
85#else 85#else
86 GetMasterPwWndImpl pwWnd; 86 GetMasterPwWndImpl pwWnd;
87#endif 87#endif
88 if (pwWnd.exec() != 1) 88 if (pwWnd.exec() != 1)
89 return ""; 89 return "";
90 pw = pwWnd.pwLineEdit->text(); 90 pw = pwWnd.pwLineEdit->text();
91 } 91 }
92 92
93 return pw; 93 return pw;
94} 94}
95 95
96QString PwMDocUi::requestNewMpw(bool *chipcard) 96QString PwMDocUi::requestNewMpw(bool *chipcard)
97{ 97{
98 QString pw; 98 QString pw;
99 SetMasterPwWndImpl pwWnd(currentView); 99 SetMasterPwWndImpl pwWnd(currentView);
100 pwWnd.setPwMKeyCard(keyCard); 100 pwWnd.setPwMKeyCard(keyCard);
101 if (!chipcard) { 101 if (!chipcard) {
102#ifndef PWM_EMBEDDED 102#ifndef PWM_EMBEDDED
103 pwWnd.mainTab->removePage(pwWnd.mainTab->page(1)); 103 pwWnd.mainTab->removePage(pwWnd.mainTab->page(1));
104#else 104#else
105 pwWnd.mainTab->removePage(pwWnd.tab_2); 105 pwWnd.mainTab->removePage(pwWnd.tab_2);
106#endif 106#endif
107 } 107 }
108 108
109 if (pwWnd.exec() != 1) 109 if (pwWnd.exec() != 1)
110 return ""; 110 return "";
111 pw = pwWnd.getPw(chipcard).c_str(); 111 pw = pwWnd.getPw(chipcard).c_str();
112 112
113 return pw; 113 return pw;
114} 114}
115 115
116QString PwMDocUi::requestMpwChange(const QString *currentPw, bool *chipcard) 116QString PwMDocUi::requestMpwChange(const QString *currentPw, bool *chipcard)
117{ 117{
118 QString pw(requestMpw(*chipcard)); 118 QString pw(requestMpw(*chipcard));
119 if (pw == "") 119 if (pw == "")
120 return ""; 120 return "";
121 if (pw != *currentPw) { 121 if (pw != *currentPw) {
122 wrongMpwMsgBox(*chipcard); 122 wrongMpwMsgBox(*chipcard);
123 return ""; 123 return "";
124 } 124 }
125 125
126 pw = requestNewMpw(chipcard); 126 pw = requestNewMpw(chipcard);
127 if (pw == "") 127 if (pw == "")
128 return ""; 128 return "";
129 return pw; 129 return pw;
130} 130}
131 131
132void PwMDocUi::wrongMpwMsgBox(bool chipcard, QString prefix, QString postfix) 132void PwMDocUi::wrongMpwMsgBox(bool chipcard, QString prefix, QString postfix)
133{ 133{
134 QString msg; 134 QString msg;
135 if (prefix != "") { 135 if (prefix != "") {
136 msg += prefix; 136 msg += prefix;
137 msg += "\n"; 137 msg += "\n";
138 } 138 }
139 139
140 if (chipcard) { 140 if (chipcard) {
141 msg += i18n("Wrong key-card!\n" 141 msg += i18n("Wrong key-card!\n"
142 "Please try again with the\n" 142 "Please try again with the\n"
143 "correct key-card."); 143 "correct key-card.");
144 } else { 144 } else {
145 msg += i18n("Wrong master-password!\n" 145 msg += i18n("Wrong master-password!\n"
146 "Please try again."); 146 "Please try again.");
147 } 147 }
148 148
149 if (postfix != "") { 149 if (postfix != "") {
150 msg += "\n"; 150 msg += "\n";
151 msg += postfix; 151 msg += postfix;
152 } 152 }
153 KMessageBox::error(currentView, msg, 153 KMessageBox::error(currentView, msg,
154 (chipcard) ? (i18n("wrong chipcard")) 154 (chipcard) ? (i18n("wrong chipcard"))
155 : (i18n("password error"))); 155 : (i18n("password error")));
156} 156}
157 157
158void PwMDocUi::noMpwMsgBox(bool chipcard, QString prefix, QString postfix) 158void PwMDocUi::noMpwMsgBox(bool chipcard, QString prefix, QString postfix)
159{ 159{
160 QString msg; 160 QString msg;
161 if (prefix != "") { 161 if (prefix != "") {
162 msg += prefix; 162 msg += prefix;
163 msg += "\n"; 163 msg += "\n";
164 } 164 }
165 165
166 if (chipcard) { 166 if (chipcard) {
167 msg += i18n("No key-card found!\n" 167 msg += i18n("No key-card found!\n"
168 "Please insert the\n" 168 "Please insert the\n"
169 "correct key-card."); 169 "correct key-card.");
170 } else { 170 } else {
171 msg += i18n("No master-password given!"); 171 msg += i18n("No master-password given!");
172 } 172 }
173 173
174 if (postfix != "") { 174 if (postfix != "") {
175 msg += "\n"; 175 msg += "\n";
176 msg += postfix; 176 msg += postfix;
177 } 177 }
178 KMessageBox::error(currentView, msg, 178 KMessageBox::error(currentView, msg,
179 (chipcard) ? (i18n("no chipcard")) 179 (chipcard) ? (i18n("no chipcard"))
180 : (i18n("password error"))); 180 : (i18n("password error")));
181} 181}
182 182
183void PwMDocUi::rootAlertMsgBox() 183void PwMDocUi::rootAlertMsgBox()
184{ 184{
185 KMessageBox::error(currentView, 185 KMessageBox::error(currentView,
186 i18n("This feature is not available,n" 186 i18n("This feature is not available,n"
187 "if you execute PwM with \"root\" \n" 187 "if you execute PwM with \"root\" \n"
188 "UID 0 privileges, for security reasons!"), 188 "UID 0 privileges, for security reasons!"),
189 i18n("not allowed as root!")); 189 i18n("not allowed as root!"));
190} 190}
191 191
192void PwMDocUi::cantDeeplock_notSavedMsgBox() 192void PwMDocUi::cantDeeplock_notSavedMsgBox()
193{ 193{
194 KMessageBox::error(currentView, 194 KMessageBox::error(currentView,
195 i18n("Can't deep-lock, because the document\n" 195 i18n("Can't deep-lock, because the document\n"
196 "hasn't been saved, yet. Please save\n" 196 "hasn't been saved, yet. Please save\n"
197 "to a file and try again."), 197 "to a file and try again."),
198 i18n("not saved, yet")); 198 i18n("not saved, yet"));
199} 199}
200 200
201void PwMDocUi::gpmPwLenErrMsgBox() 201void PwMDocUi::gpmPwLenErrMsgBox()
202{ 202{
203 KMessageBox::error(currentView, 203 KMessageBox::error(currentView,
204 i18n("GPasman does not support passwords\n" 204 i18n("GPasman does not support passwords\n"
205 "shorter than 4 characters! Please try\n" 205 "shorter than 4 characters! Please try\n"
206 "again with a longer password."), 206 "again with a longer password."),
207 i18n("password too short")); 207 i18n("password too short"));
208} 208}
209 209
210int PwMDocUi::dirtyAskSave(const QString &docTitle) 210int PwMDocUi::dirtyAskSave(const QString &docTitle)
211{ 211{
212 int ret; 212 int ret;
213#ifndef PWM_EMBEDDED 213#ifndef PWM_EMBEDDED
214 ret = KMessageBox::questionYesNoCancel(currentView, 214 ret = KMessageBox::questionYesNoCancel(currentView,
215 i18n("The list \"") + 215 i18n("The list \"") +
216 docTitle + 216 docTitle +
217 i18n 217 i18n
218 ("\" has been modified.\n" 218 ("\" has been modified.\n"
219 "Do you want to save it?"), 219 "Do you want to save it?"),
220 i18n("save?")); 220 i18n("save?"));
221 if (ret == KMessageBox::Yes) { 221 if (ret == KMessageBox::Yes) {
222 return 0; 222 return 0;
223 } else if (ret == KMessageBox::No) { 223 } else if (ret == KMessageBox::No) {
224 return 1; 224 return 1;
225 } 225 }
226#else 226#else
227 ret = KMessageBox::warningYesNoCancel(currentView, 227 ret = KMessageBox::warningYesNoCancel(currentView,
228 i18n("The list \"") + 228 i18n("The list \"") +
229 docTitle + 229 docTitle +
230 i18n 230 i18n
231 ("\"\nhas been modified.\n" 231 ("\"\nhas been modified.\n"
232 "Do you want to save it?"), 232 "Do you want to save it?"),
233 i18n("save?")); 233 i18n("save?"));
234 if (ret == KMessageBox::Yes) { 234 if (ret == KMessageBox::Yes) {
235 return 0; 235 return 0;
236 } else if (ret == KMessageBox::No) { 236 } else if (ret == KMessageBox::No) {
237 return 1; 237 return 1;
238 } 238 }
239 239
240#endif 240#endif
241 241
242 // cancel 242 // cancel
243 return -1; 243 return -1;
244} 244}
245 245
246bool PwMDocUi::saveDocUi(PwMDoc *doc) 246bool PwMDocUi::saveDocUi(PwMDoc *doc)
247{ 247{
248 PWM_ASSERT(doc); 248 PWM_ASSERT(doc);
249 doc->timer()->getLock(DocTimer::id_autoLockTimer); 249 doc->timer()->getLock(DocTimer::id_autoLockTimer);
250 if (doc->isDocEmpty()) { 250 if (doc->isDocEmpty()) {
251 KMessageBox::information(currentView, 251 KMessageBox::information(currentView,
252 i18n 252 i18n
253 ("Sorry, there's nothing to save.\n" 253 ("Sorry, there's nothing to save.\n"
254 "Please first add some passwords."), 254 "Please first add some passwords."),
255 i18n("nothing to do")); 255 i18n("nothing to do"));
256 doc->timer()->putLock(DocTimer::id_autoLockTimer); 256 doc->timer()->putLock(DocTimer::id_autoLockTimer);
257 return true; 257 return true;
258 } 258 }
259 PwMerror ret = doc->saveDoc(conf()->confGlobCompression()); 259 PwMerror ret = doc->saveDoc(conf()->confGlobCompression());
260 if (ret == e_filename) { 260 if (ret == e_filename) {
261 doc->timer()->putLock(DocTimer::id_autoLockTimer); 261 doc->timer()->putLock(DocTimer::id_autoLockTimer);
262 return saveAsDocUi(doc); 262 return saveAsDocUi(doc);
263 } else if (ret == e_weakPw) { 263 } else if (ret == e_weakPw) {
264 KMessageBox::error(currentView, 264 KMessageBox::error(currentView,
265 i18n("Error: This is a weak password.\n" 265 i18n("Error: This is a weak password.\n"
266 "Please select another password."), 266 "Please select another password."),
267 i18n("weak password")); 267 i18n("weak password"));
268 doc->timer()->putLock(DocTimer::id_autoLockTimer); 268 doc->timer()->putLock(DocTimer::id_autoLockTimer);
269 return false; 269 return false;
270 } else if (ret == e_fileBackup) { 270 } else if (ret == e_fileBackup) {
271 KMessageBox::error(currentView, 271 KMessageBox::error(currentView,
272 i18n("Error: Couldn't make backup-file!"), 272 i18n("Error: Couldn't make backup-file!"),
273 i18n("backup failed")); 273 i18n("backup failed"));
274 doc->timer()->putLock(DocTimer::id_autoLockTimer); 274 doc->timer()->putLock(DocTimer::id_autoLockTimer);
275 return false; 275 return false;
276 } else if (ret == e_noPw ||
277 ret == e_wrongPw ||
278 ret == e_openFile) {
279 doc->timer()->putLock(DocTimer::id_autoLockTimer);
280 return false;
276 } else if (ret != e_success) { 281 } else if (ret != e_success) {
277 KMessageBox::error(currentView, 282 KMessageBox::error(currentView,
278 i18n("Error: Couldn't write to file.\n" 283 i18n("Error: Couldn't write to file.\n"
279 "Please check if you have permission to\n" 284 "Please check if you have permission to\n"
280 "write to the file in that directory."), 285 "write to the file in that directory."),
281 i18n("error while writing")); 286 i18n("error while writing"));
282 doc->timer()->putLock(DocTimer::id_autoLockTimer); 287 doc->timer()->putLock(DocTimer::id_autoLockTimer);
283 return false; 288 return false;
284 } 289 }
285 doc->timer()->putLock(DocTimer::id_autoLockTimer); 290 doc->timer()->putLock(DocTimer::id_autoLockTimer);
286 return true; 291 return true;
287} 292}
288 293
289bool PwMDocUi::saveAsDocUi(PwMDoc *doc) 294bool PwMDocUi::saveAsDocUi(PwMDoc *doc)
290{ 295{
291 PWM_ASSERT(doc); 296 PWM_ASSERT(doc);
292 doc->timer()->getLock(DocTimer::id_autoLockTimer); 297 doc->timer()->getLock(DocTimer::id_autoLockTimer);
293 if (doc->isDocEmpty()) { 298 if (doc->isDocEmpty()) {
294 KMessageBox::information(currentView, 299 KMessageBox::information(currentView,
295 i18n 300 i18n
296 ("Sorry, there's nothing to save.\n" 301 ("Sorry, there's nothing to save.\n"
297 "Please first add some passwords."), 302 "Please first add some passwords."),
298 i18n("nothing to do")); 303 i18n("nothing to do"));
299 doc->timer()->putLock(DocTimer::id_autoLockTimer); 304 doc->timer()->putLock(DocTimer::id_autoLockTimer);
300 return true; 305 return true;
301 } 306 }
302#ifndef PWM_EMBEDDED 307#ifndef PWM_EMBEDDED
303 QString fn(KFileDialog::getSaveFileName(QString::null, 308 QString fn(KFileDialog::getSaveFileName(QString::null,
304 i18n("*.pwm|PwManager Password file"), 309 i18n("*.pwm|PwManager Password file"),
305 currentView)); 310 currentView));
306#else 311#else
307 QString fn = locateLocal( "data", KGlobal::getAppName() + "/*.pwm" ); 312 QString fn = locateLocal( "data", KGlobal::getAppName() + "/*.pwm" );
308 fn = KFileDialog::getSaveFileName(fn, 313 fn = KFileDialog::getSaveFileName(fn,
309 i18n("password filename(*.pwm)"), 314 i18n("password filename(*.pwm)"),
310 currentView); 315 currentView);
311 316
312#endif 317#endif
313 if (fn == "") { 318 if (fn == "") {
314 doc->timer()->putLock(DocTimer::id_autoLockTimer); 319 doc->timer()->putLock(DocTimer::id_autoLockTimer);
315 return false; 320 return false;
316 } 321 }
317 if (fn.right(4) != ".pwm") 322 if (fn.right(4) != ".pwm")
318 fn += ".pwm"; 323 fn += ".pwm";
319 324
320 PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); 325 PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn);
321 if (ret != e_success) { 326 if (ret == e_noPw ||
327 ret == e_wrongPw ||
328 ret == e_openFile) {
329 doc->timer()->putLock(DocTimer::id_autoLockTimer);
330 return false;
331 } else if (ret != e_success) {
322 KMessageBox::error(currentView, 332 KMessageBox::error(currentView,
323 i18n("Error: Couldn't write to file.\n" 333 i18n("Error: Couldn't write to file.\n"
324 "Please check if you have permission to\n" 334 "Please check if you have permission to\n"
325 "write to the file in that directory."), 335 "write to the file in that directory."),
326 i18n("error while writing")); 336 i18n("error while writing"));
327 doc->timer()->putLock(DocTimer::id_autoLockTimer); 337 doc->timer()->putLock(DocTimer::id_autoLockTimer);
328 return false; 338 return false;
329 } 339 }
330 doc->timer()->putLock(DocTimer::id_autoLockTimer); 340 doc->timer()->putLock(DocTimer::id_autoLockTimer);
331 return true; 341 return true;
332} 342}
333 343
334bool PwMDocUi::openDocUi(PwMDoc *doc, 344bool PwMDocUi::openDocUi(PwMDoc *doc,
335 QString filename, 345 QString filename,
336 bool openDeepLocked) 346 bool openDeepLocked)
337{ 347{
338 if (filename.isEmpty()) 348 if (filename.isEmpty())
339 { 349 {
340#ifndef PWM_EMBEDDED 350#ifndef PWM_EMBEDDED
341 filename = KFileDialog::getOpenFileName(QString::null, 351 filename = KFileDialog::getOpenFileName(QString::null,
342 i18n("*.pwm|PwManager Password file\n" 352 i18n("*.pwm|PwManager Password file\n"
343 "*|All files"), getCurrentView()); 353 "*|All files"), getCurrentView());
344#else 354#else
345 filename = locateLocal( "data", KGlobal::getAppName() + "/*.pwm"); 355 filename = locateLocal( "data", KGlobal::getAppName() + "/*.pwm");
346 filename = KFileDialog::getOpenFileName(filename, 356 filename = KFileDialog::getOpenFileName(filename,
347 i18n("password filename(*.pwm)"), getCurrentView()); 357 i18n("password filename(*.pwm)"), getCurrentView());
348#endif 358#endif
349 } 359 }
350 if (filename.isEmpty()) 360 if (filename.isEmpty())
351 goto cancelOpen; 361 goto cancelOpen;
352 PwMerror ret; 362 PwMerror ret;
353 while (true) { 363 while (true) {
354 int lockStat = -1; 364 int lockStat = -1;
355 if (openDeepLocked) { 365 if (openDeepLocked) {
356 lockStat = 2; 366 lockStat = 2;
357 } else { 367 } else {
358 if (conf()->confGlobUnlockOnOpen()) { 368 if (conf()->confGlobUnlockOnOpen()) {
359 lockStat = 0; 369 lockStat = 0;
360 } else { 370 } else {
361 lockStat = 1; 371 lockStat = 1;
362 } 372 }
363 } 373 }
364 ret = doc->openDoc(&filename, lockStat); 374 ret = doc->openDoc(&filename, lockStat);
365 //qDebug("pwmdocui::OpenDocui %i", ret); 375 //qDebug("pwmdocui::OpenDocui %i", ret);
366 if (ret != e_success) { 376 if (ret != e_success) {
367 if (ret == e_readFile || ret == e_openFile) { 377 if (ret == e_readFile || ret == e_openFile) {
368 KMessageBox::error(getCurrentView(), 378 KMessageBox::error(getCurrentView(),
369 i18n("Could not read file!") 379 i18n("Could not read file!")
370 + "\n" 380 + "\n"
371 + filename, 381 + filename,
372 i18n("file error")); 382 i18n("file error"));
373 goto cancelOpen; 383 goto cancelOpen;
374 } 384 }
375 if (ret == e_alreadyOpen) { 385 if (ret == e_alreadyOpen) {
376 KMessageBox::error(getCurrentView(), 386 KMessageBox::error(getCurrentView(),
377 i18n("This file is already open."), 387 i18n("This file is already open."),
378 i18n("already open")); 388 i18n("already open"));
379 goto cancelOpen; 389 goto cancelOpen;
380 } 390 }
381 if (ret == e_fileVer) { 391 if (ret == e_fileVer) {
382 KMessageBox::error(getCurrentView(), 392 KMessageBox::error(getCurrentView(),
383 i18n 393 i18n
384 ("File-version is not supported!\n" 394 ("File-version is not supported!\n"
385 "Did you create this file with an\nolder or newer version of PwM?"), 395 "Did you create this file with an\nolder or newer version of PwM?"),
386 i18n 396 i18n
387 ("incompatible version")); 397 ("incompatible version"));
388 goto cancelOpen; 398 goto cancelOpen;
389 } 399 }
390 if (ret == e_wrongPw) { 400 if (ret == e_wrongPw) {
391 continue; 401 continue;
392 } 402 }
393 if (ret == e_noPw) { 403 if (ret == e_noPw) {
394 goto cancelOpen; 404 goto cancelOpen;
395 } 405 }
396 if (ret == e_fileFormat) { 406 if (ret == e_fileFormat) {
397 KMessageBox::error(getCurrentView(), 407 KMessageBox::error(getCurrentView(),
398 i18n 408 i18n
399 ("Sorry, this file has not been recognized\n" 409 ("Sorry, this file has not been recognized\n"
400 "as a PwM Password file.\n" 410 "as a PwM Password file.\n"
401 "Probably you have selected the wrong file."), 411 "Probably you have selected the wrong file."),
402 i18n 412 i18n
403 ("no PwM password-file")); 413 ("no PwM password-file"));
404 goto cancelOpen; 414 goto cancelOpen;
405 } 415 }
406 if (ret == e_fileCorrupt) { 416 if (ret == e_fileCorrupt) {
407 KMessageBox::error(getCurrentView(), 417 KMessageBox::error(getCurrentView(),
408 i18n 418 i18n
409 ("File corrupt!\n" 419 ("File corrupt!\n"
410 "Maybe the media, you stored this file on,\n" 420 "Maybe the media, you stored this file on,\n"
411 "had bad sectors?"), 421 "had bad sectors?"),
412 i18n 422 i18n
413 ("checksum error")); 423 ("checksum error"));
414 goto cancelOpen; 424 goto cancelOpen;
415 } 425 }
416 } 426 }
417 break; 427 break;
418 } 428 }
419 return true; 429 return true;
420 430
421 cancelOpen: 431 cancelOpen:
422 return false; 432 return false;
423} 433}
424 434
425QString PwMDocUi::string_defaultCategory() 435QString PwMDocUi::string_defaultCategory()
426{ 436{
427 return i18n("Default"); 437 return i18n("Default");
428} 438}
429 439
430QString PwMDocUi::string_locked() 440QString PwMDocUi::string_locked()
431{ 441{
432 return i18n("<LOCKED>"); 442 return i18n("<LOCKED>");
433} 443}
434 444
435QString PwMDocUi::string_deepLockedShort() 445QString PwMDocUi::string_deepLockedShort()
436{ 446{
437 return i18n("DEEP-LOCKED"); 447 return i18n("DEEP-LOCKED");
438} 448}
439 449
440QString PwMDocUi::string_deepLockedLong() 450QString PwMDocUi::string_deepLockedLong()
441{ 451{
442 return i18n("This file is DEEP-LOCKED!\n" 452 return i18n("This file is DEEP-LOCKED!\n"
443 "That means all data has been encrypted\n" 453 "That means all data has been encrypted\n"
444 "and written out to the file. If you want\n" 454 "and written out to the file. If you want\n"
445 "to see the entries, please UNLOCK the file.\n" 455 "to see the entries, please UNLOCK the file.\n"
446 "While unlocking, you will be prompted for the\n" 456 "While unlocking, you will be prompted for the\n"
447 "master-password or the key-card."); 457 "master-password or the key-card.");
448} 458}
449 459
450QString PwMDocUi::string_defaultTitle() 460QString PwMDocUi::string_defaultTitle()
451{ 461{
452 return i18n("Untitled"); 462 return i18n("Untitled");
453} 463}
454 464
455#ifndef PWM_EMBEDDED 465#ifndef PWM_EMBEDDED
456#include "pwmdocui.moc" 466#include "pwmdocui.moc"
457#endif 467#endif