summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2004-12-04 22:43:14 (UTC)
committer zautrix <zautrix>2004-12-04 22:43:14 (UTC)
commite4e75984b6cb581d87d436cb6c5140eb57dbdc51 (patch) (unidiff)
treebd3a1ddf191fd16d24dad9910c0b806cee23000e
parentac994c86c3037dbe2273e62c46115b942b09fdcc (diff)
downloadkdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.zip
kdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.tar.gz
kdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.tar.bz2
set pwmpi update timer from 10 sec to 5 min
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp3
-rw-r--r--pwmanager/pwmanager/pwmview.cpp1
2 files changed, 3 insertions, 1 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index a740d6d..1f15ffd 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,2123 +1,2124 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager 14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
18 **************************************************************************/ 18 **************************************************************************/
19 19
20#include "pwmdoc.h" 20#include "pwmdoc.h"
21#include "pwmview.h" 21#include "pwmview.h"
22#include "blowfish.h" 22#include "blowfish.h"
23#include "sha1.h" 23#include "sha1.h"
24#include "globalstuff.h" 24#include "globalstuff.h"
25#include "gpasmanfile.h" 25#include "gpasmanfile.h"
26#include "serializer.h" 26#include "serializer.h"
27#include "compressgzip.h" 27#include "compressgzip.h"
28//US#include "compressbzip2.h" 28//US#include "compressbzip2.h"
29#include "randomizer.h" 29#include "randomizer.h"
30#include "pwminit.h" 30#include "pwminit.h"
31#include "libgcryptif.h" 31#include "libgcryptif.h"
32#ifdef PWM_EMBEDDED 32#ifdef PWM_EMBEDDED
33#include "pwmprefs.h" 33#include "pwmprefs.h"
34#include "kglobal.h" 34#include "kglobal.h"
35#endif 35#endif
36 36
37#include <kmessagebox.h> 37#include <kmessagebox.h>
38#include <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#ifndef _WIN32_ 58#ifndef _WIN32_
59#include <unistd.h> 59#include <unistd.h>
60#include <stdint.h> 60#include <stdint.h>
61#endif 61#endif
62 62
63#ifdef PWM_EMBEDDED 63#ifdef PWM_EMBEDDED
64#ifndef Q_LONG 64#ifndef Q_LONG
65#define Q_LONG long 65#define Q_LONG long
66#endif 66#endif
67 67
68#ifndef Q_ULONG 68#ifndef Q_ULONG
69#define Q_ULONG unsigned long 69#define Q_ULONG unsigned long
70#endif 70#endif
71#endif //PWM_EMBEDDED 71#endif //PWM_EMBEDDED
72 72
73 73
74//TODO: reset to its normal value. 74//TODO: reset to its normal value.
75 #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */ 75//LR set to 5 min
76 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */
76 77
77using namespace std; 78using namespace std;
78 79
79 80
80void PwMDocList::add(PwMDoc *doc, const string &id) 81void PwMDocList::add(PwMDoc *doc, const string &id)
81{ 82{
82#ifdef PWM_DEBUG 83#ifdef PWM_DEBUG
83 // check for existance of object in debug mode only. 84 // check for existance of object in debug mode only.
84 vector<listItem>::iterator begin = docList.begin(), 85 vector<listItem>::iterator begin = docList.begin(),
85 end = docList.end(), 86 end = docList.end(),
86 i = begin; 87 i = begin;
87 while (i != end) { 88 while (i != end) {
88 if (i->doc == doc) { 89 if (i->doc == doc) {
89 BUG(); 90 BUG();
90 return; 91 return;
91 } 92 }
92 ++i; 93 ++i;
93 } 94 }
94#endif 95#endif
95 listItem newItem; 96 listItem newItem;
96 newItem.doc = doc; 97 newItem.doc = doc;
97 newItem.docId = id; 98 newItem.docId = id;
98 docList.push_back(newItem); 99 docList.push_back(newItem);
99} 100}
100 101
101void PwMDocList::edit(PwMDoc *doc, const string &newId) 102void PwMDocList::edit(PwMDoc *doc, const string &newId)
102{ 103{
103 vector<listItem>::iterator begin = docList.begin(), 104 vector<listItem>::iterator begin = docList.begin(),
104 end = docList.end(), 105 end = docList.end(),
105 i = begin; 106 i = begin;
106 while (i != end) { 107 while (i != end) {
107 if (i->doc == doc) { 108 if (i->doc == doc) {
108 i->docId = newId; 109 i->docId = newId;
109 return; 110 return;
110 } 111 }
111 ++i; 112 ++i;
112 } 113 }
113} 114}
114 115
115void PwMDocList::del(PwMDoc *doc) 116void PwMDocList::del(PwMDoc *doc)
116{ 117{
117 vector<listItem>::iterator begin = docList.begin(), 118 vector<listItem>::iterator begin = docList.begin(),
118 end = docList.end(), 119 end = docList.end(),
119 i = begin; 120 i = begin;
120 while (i != end) { 121 while (i != end) {
121 if (i->doc == doc) { 122 if (i->doc == doc) {
122 docList.erase(i); 123 docList.erase(i);
123 return; 124 return;
124 } 125 }
125 ++i; 126 ++i;
126 } 127 }
127} 128}
128 129
129bool PwMDocList::find(const string &id, listItem *ret) 130bool PwMDocList::find(const string &id, listItem *ret)
130{ 131{
131 vector<listItem>::iterator begin = docList.begin(), 132 vector<listItem>::iterator begin = docList.begin(),
132 end = docList.end(), 133 end = docList.end(),
133 i = begin; 134 i = begin;
134 while (i != end) { 135 while (i != end) {
135 if (i->docId == id) { 136 if (i->docId == id) {
136 if (ret) 137 if (ret)
137 *ret = *i; 138 *ret = *i;
138 return true; 139 return true;
139 } 140 }
140 ++i; 141 ++i;
141 } 142 }
142 return false; 143 return false;
143} 144}
144 145
145 146
146 147
147DocTimer::DocTimer(PwMDoc *_doc) 148DocTimer::DocTimer(PwMDoc *_doc)
148 : doc (_doc) 149 : doc (_doc)
149 , mpwLock (0) 150 , mpwLock (0)
150 , autoLockLock (0) 151 , autoLockLock (0)
151 , metaCheckLock (0) 152 , metaCheckLock (0)
152{ 153{
153 mpwTimer = new QTimer; 154 mpwTimer = new QTimer;
154 autoLockTimer = new QTimer; 155 autoLockTimer = new QTimer;
155 metaCheckTimer = new QTimer; 156 metaCheckTimer = new QTimer;
156 connect(mpwTimer, SIGNAL(timeout()), 157 connect(mpwTimer, SIGNAL(timeout()),
157 this, SLOT(mpwTimeout())); 158 this, SLOT(mpwTimeout()));
158 connect(autoLockTimer, SIGNAL(timeout()), 159 connect(autoLockTimer, SIGNAL(timeout()),
159 this, SLOT(autoLockTimeout())); 160 this, SLOT(autoLockTimeout()));
160 connect(metaCheckTimer, SIGNAL(timeout()), 161 connect(metaCheckTimer, SIGNAL(timeout()),
161 this, SLOT(metaCheckTimeout())); 162 this, SLOT(metaCheckTimeout()));
162} 163}
163 164
164DocTimer::~DocTimer() 165DocTimer::~DocTimer()
165{ 166{
166 delete mpwTimer; 167 delete mpwTimer;
167 delete autoLockTimer; 168 delete autoLockTimer;
168 delete metaCheckTimer; 169 delete metaCheckTimer;
169} 170}
170 171
171void DocTimer::start(TimerIDs timer) 172void DocTimer::start(TimerIDs timer)
172{ 173{
173 switch (timer) { 174 switch (timer) {
174 case id_mpwTimer: 175 case id_mpwTimer:
175 if (mpwTimer->isActive()) 176 if (mpwTimer->isActive())
176 mpwTimer->stop(); 177 mpwTimer->stop();
177 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 178 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
178 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); 179 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
179 break; 180 break;
180 case id_autoLockTimer: 181 case id_autoLockTimer:
181 if (autoLockTimer->isActive()) 182 if (autoLockTimer->isActive())
182 autoLockTimer->stop(); 183 autoLockTimer->stop();
183 if (conf()->confGlobLockTimeout() > 0) 184 if (conf()->confGlobLockTimeout() > 0)
184 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); 185 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
185 break; 186 break;
186 case id_metaCheckTimer: 187 case id_metaCheckTimer:
187 if (metaCheckTimer->isActive()) 188 if (metaCheckTimer->isActive())
188 metaCheckTimer->stop(); 189 metaCheckTimer->stop();
189 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 190 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
190 break; 191 break;
191 } 192 }
192} 193}
193 194
194void DocTimer::stop(TimerIDs timer) 195void DocTimer::stop(TimerIDs timer)
195{ 196{
196 switch (timer) { 197 switch (timer) {
197 case id_mpwTimer: 198 case id_mpwTimer:
198 mpwTimer->stop(); 199 mpwTimer->stop();
199 break; 200 break;
200 case id_autoLockTimer: 201 case id_autoLockTimer:
201 autoLockTimer->stop(); 202 autoLockTimer->stop();
202 break; 203 break;
203 case id_metaCheckTimer: 204 case id_metaCheckTimer:
204 metaCheckTimer->stop(); 205 metaCheckTimer->stop();
205 break; 206 break;
206 } 207 }
207} 208}
208 209
209void DocTimer::getLock(TimerIDs timer) 210void DocTimer::getLock(TimerIDs timer)
210{ 211{
211 switch (timer) { 212 switch (timer) {
212 case id_mpwTimer: 213 case id_mpwTimer:
213 ++mpwLock; 214 ++mpwLock;
214 break; 215 break;
215 case id_autoLockTimer: 216 case id_autoLockTimer:
216 ++autoLockLock; 217 ++autoLockLock;
217 break; 218 break;
218 case id_metaCheckTimer: 219 case id_metaCheckTimer:
219 ++metaCheckLock; 220 ++metaCheckLock;
220 break; 221 break;
221 } 222 }
222} 223}
223 224
224void DocTimer::putLock(TimerIDs timer) 225void DocTimer::putLock(TimerIDs timer)
225{ 226{
226 switch (timer) { 227 switch (timer) {
227 case id_mpwTimer: 228 case id_mpwTimer:
228 if (mpwLock) 229 if (mpwLock)
229 --mpwLock; 230 --mpwLock;
230 break; 231 break;
231 case id_autoLockTimer: 232 case id_autoLockTimer:
232 if (autoLockLock) 233 if (autoLockLock)
233 --autoLockLock; 234 --autoLockLock;
234 break; 235 break;
235 case id_metaCheckTimer: 236 case id_metaCheckTimer:
236 if (metaCheckLock) 237 if (metaCheckLock)
237 --metaCheckLock; 238 --metaCheckLock;
238 break; 239 break;
239 } 240 }
240} 241}
241 242
242void DocTimer::mpwTimeout() 243void DocTimer::mpwTimeout()
243{ 244{
244 if (mpwLock) { 245 if (mpwLock) {
245 mpwTimer->start(1000, true); 246 mpwTimer->start(1000, true);
246 return; 247 return;
247 } 248 }
248 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 249 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
249} 250}
250 251
251void DocTimer::autoLockTimeout() 252void DocTimer::autoLockTimeout()
252{ 253{
253 if (autoLockLock) { 254 if (autoLockLock) {
254 autoLockTimer->start(1000, true); 255 autoLockTimer->start(1000, true);
255 return; 256 return;
256 } 257 }
257 if (conf()->confGlobAutoDeepLock() && 258 if (conf()->confGlobAutoDeepLock() &&
258 doc->filename != QString::null && 259 doc->filename != QString::null &&
259 doc->filename != "") { 260 doc->filename != "") {
260 doc->deepLock(true); 261 doc->deepLock(true);
261 } else { 262 } else {
262 doc->lockAll(true); 263 doc->lockAll(true);
263 } 264 }
264} 265}
265 266
266void DocTimer::metaCheckTimeout() 267void DocTimer::metaCheckTimeout()
267{ 268{
268 if (metaCheckLock) { 269 if (metaCheckLock) {
269 // check again in one second. 270 // check again in one second.
270 metaCheckTimer->start(1000, true); 271 metaCheckTimer->start(1000, true);
271 return; 272 return;
272 } 273 }
273 if (doc->isDeepLocked()) { 274 if (doc->isDeepLocked()) {
274 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 275 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
275 return; 276 return;
276 } 277 }
277 if (doc->isDocEmpty()) { 278 if (doc->isDocEmpty()) {
278 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 279 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
279 return; 280 return;
280 } 281 }
281#ifdef CONFIG_KWALLETIF 282#ifdef CONFIG_KWALLETIF
282 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 283 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
283 if (kwlEmu) 284 if (kwlEmu)
284 kwlEmu->suspendDocSignals(); 285 kwlEmu->suspendDocSignals();
285#endif // CONFIG_KWALLETIF 286#endif // CONFIG_KWALLETIF
286 /* We simply trigger all views to update their 287 /* We simply trigger all views to update their
287 * displayed values. This way they have a chance 288 * displayed values. This way they have a chance
288 * to get notified when some meta changes over time. 289 * to get notified when some meta changes over time.
289 * (for example an entry expired). 290 * (for example an entry expired).
290 * The _view_ is responsive for not updating its 291 * The _view_ is responsive for not updating its
291 * contents if nothing really changed! 292 * contents if nothing really changed!
292 */ 293 */
293 emit doc->dataChanged(doc); 294 emit doc->dataChanged(doc);
294#ifdef CONFIG_KWALLETIF 295#ifdef CONFIG_KWALLETIF
295 if (kwlEmu) 296 if (kwlEmu)
296 kwlEmu->resumeDocSignals(); 297 kwlEmu->resumeDocSignals();
297#endif // CONFIG_KWALLETIF 298#endif // CONFIG_KWALLETIF
298 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 299 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
299} 300}
300 301
301 302
302 303
303PwMDocList PwMDoc::openDocList; 304PwMDocList PwMDoc::openDocList;
304unsigned int PwMDocList::unnamedDocCnt = 1; 305unsigned int PwMDocList::unnamedDocCnt = 1;
305 306
306PwMDoc::PwMDoc(QObject *parent, const char *name) 307PwMDoc::PwMDoc(QObject *parent, const char *name)
307 : PwMDocUi(parent, name) 308 : PwMDocUi(parent, name)
308 , dataChangedLock (0) 309 , dataChangedLock (0)
309{ 310{
310 deleted = false; 311 deleted = false;
311 unnamedNum = 0; 312 unnamedNum = 0;
312 getOpenDocList()->add(this, getTitle().latin1()); 313 getOpenDocList()->add(this, getTitle().latin1());
313 curDocStat = 0; 314 curDocStat = 0;
314 setMaxNumEntries(); 315 setMaxNumEntries();
315 _timer = new DocTimer(this); 316 _timer = new DocTimer(this);
316 timer()->start(DocTimer::id_mpwTimer); 317 timer()->start(DocTimer::id_mpwTimer);
317 timer()->start(DocTimer::id_autoLockTimer); 318 timer()->start(DocTimer::id_autoLockTimer);
318 timer()->start(DocTimer::id_metaCheckTimer); 319 timer()->start(DocTimer::id_metaCheckTimer);
319 addCategory(DEFAULT_CATEGORY, 0, false); 320 addCategory(DEFAULT_CATEGORY, 0, false);
320 listView = 0; 321 listView = 0;
321 emit docCreated(this); 322 emit docCreated(this);
322} 323}
323 324
324PwMDoc::~PwMDoc() 325PwMDoc::~PwMDoc()
325{ 326{
326 emit docClosed(this); 327 emit docClosed(this);
327 getOpenDocList()->del(this); 328 getOpenDocList()->del(this);
328 delete _timer; 329 delete _timer;
329} 330}
330 331
331PwMerror PwMDoc::saveDoc(char compress, const QString *file) 332PwMerror PwMDoc::saveDoc(char compress, const QString *file)
332{ 333{
333 PwMerror ret, e; 334 PwMerror ret, e;
334 string serialized; 335 string serialized;
335 QFile f; 336 QFile f;
336 QString tmpFileMoved(QString::null); 337 QString tmpFileMoved(QString::null);
337 bool wasDeepLocked; 338 bool wasDeepLocked;
338 QString savedFilename(filename); 339 QString savedFilename(filename);
339 340
340 if (!file) { 341 if (!file) {
341 if (filename == "") 342 if (filename == "")
342 return e_filename; 343 return e_filename;
343 if (isDeepLocked()) { 344 if (isDeepLocked()) {
344 /* We don't need to save any data. 345 /* We don't need to save any data.
345 * It's already all on disk, because 346 * It's already all on disk, because
346 * we are deeplocked. 347 * we are deeplocked.
347 */ 348 */
348 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 349 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
349 ret = e_success; 350 ret = e_success;
350 return ret; 351 return ret;
351 } 352 }
352 } else { 353 } else {
353 if (*file == "" && filename == "") 354 if (*file == "" && filename == "")
354 return e_filename; 355 return e_filename;
355 if (*file != "") 356 if (*file != "")
356 filename = *file; 357 filename = *file;
357 } 358 }
358 359
359 wasDeepLocked = isDeepLocked(); 360 wasDeepLocked = isDeepLocked();
360 if (wasDeepLocked) { 361 if (wasDeepLocked) {
361 /* We are deeplocked. That means all data is already 362 /* We are deeplocked. That means all data is already
362 * on disk. BUT we need to do saving procedure, 363 * on disk. BUT we need to do saving procedure,
363 * because *file != savedFilename. 364 * because *file != savedFilename.
364 * Additionally we need to tempoarly restore 365 * Additionally we need to tempoarly restore
365 * the old "filename", because deepLock() references it. 366 * the old "filename", because deepLock() references it.
366 */ 367 */
367 QString newFilename(filename); 368 QString newFilename(filename);
368 filename = savedFilename; 369 filename = savedFilename;
369 getDataChangedLock(); 370 getDataChangedLock();
370 e = deepLock(false); 371 e = deepLock(false);
371 putDataChangedLock(); 372 putDataChangedLock();
372 filename = newFilename; 373 filename = newFilename;
373 switch (e) { 374 switch (e) {
374 case e_success: 375 case e_success:
375 break; 376 break;
376 case e_wrongPw: 377 case e_wrongPw:
377 case e_noPw: 378 case e_noPw:
378 emitDataChanged(this); 379 emitDataChanged(this);
379 return e; 380 return e;
380 default: 381 default:
381 emitDataChanged(this); 382 emitDataChanged(this);
382 return e_openFile; 383 return e_openFile;
383 } 384 }
384 } 385 }
385 386
386 if (!isPwAvailable()) { 387 if (!isPwAvailable()) {
387 /* password is not available. This means, the 388 /* password is not available. This means, the
388 * document wasn't saved, yet. 389 * document wasn't saved, yet.
389 */ 390 */
390 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 391 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
391 QString pw(requestNewMpw(&useChipcard)); 392 QString pw(requestNewMpw(&useChipcard));
392 if (pw != "") { 393 if (pw != "") {
393 currentPw = pw; 394 currentPw = pw;
394 } else { 395 } else {
395 return e_noPw; 396 return e_noPw;
396 } 397 }
397 if (useChipcard) { 398 if (useChipcard) {
398 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 399 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
399 } else { 400 } else {
400 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 401 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
401 } 402 }
402 } 403 }
403 404
404 int _cryptAlgo = conf()->confGlobCryptAlgo(); 405 int _cryptAlgo = conf()->confGlobCryptAlgo();
405 int _hashAlgo = conf()->confGlobHashAlgo(); 406 int _hashAlgo = conf()->confGlobHashAlgo();
406 407
407 // sanity check for the selected algorithms 408 // sanity check for the selected algorithms
408 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 409 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
409 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 410 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
410 printWarn("Invalid Crypto-Algorithm selected! " 411 printWarn("Invalid Crypto-Algorithm selected! "
411 "Config-file seems to be corrupt. " 412 "Config-file seems to be corrupt. "
412 "Falling back to Blowfish."); 413 "Falling back to Blowfish.");
413 _cryptAlgo = PWM_CRYPT_BLOWFISH; 414 _cryptAlgo = PWM_CRYPT_BLOWFISH;
414 } 415 }
415 if (_hashAlgo < PWM_HASH_SHA1 || 416 if (_hashAlgo < PWM_HASH_SHA1 ||
416 _hashAlgo > PWM_HASH_TIGER) { 417 _hashAlgo > PWM_HASH_TIGER) {
417 printWarn("Invalid Hash-Algorithm selected! " 418 printWarn("Invalid Hash-Algorithm selected! "
418 "Config-file seems to be corrupt. " 419 "Config-file seems to be corrupt. "
419 "Falling back to SHA1."); 420 "Falling back to SHA1.");
420 _hashAlgo = PWM_HASH_SHA1; 421 _hashAlgo = PWM_HASH_SHA1;
421 } 422 }
422 char cryptAlgo = static_cast<char>(_cryptAlgo); 423 char cryptAlgo = static_cast<char>(_cryptAlgo);
423 char hashAlgo = static_cast<char>(_hashAlgo); 424 char hashAlgo = static_cast<char>(_hashAlgo);
424 425
425 if (conf()->confGlobMakeFileBackup()) { 426 if (conf()->confGlobMakeFileBackup()) {
426 if (!backupFile(filename)) 427 if (!backupFile(filename))
427 return e_fileBackup; 428 return e_fileBackup;
428 } 429 }
429 if (QFile::exists(filename)) { 430 if (QFile::exists(filename)) {
430 /* Move the existing file to some tmp file. 431 /* Move the existing file to some tmp file.
431 * When saving file succeeds, delete tmp file. Otherwise 432 * When saving file succeeds, delete tmp file. Otherwise
432 * move tmp file back. See below. 433 * move tmp file back. See below.
433 */ 434 */
434 Randomizer *rnd = Randomizer::obj(); 435 Randomizer *rnd = Randomizer::obj();
435 char rnd_buf[5]; 436 char rnd_buf[5];
436 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 437 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
437 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 438 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
438 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 439 tmpFileMoved = filename + "." + rnd_buf + ".mv";
439 if (!copyFile(filename, tmpFileMoved)) 440 if (!copyFile(filename, tmpFileMoved))
440 return e_openFile; 441 return e_openFile;
441 if (!QFile::remove(filename)) { 442 if (!QFile::remove(filename)) {
442 printWarn(string("removing orig file ") 443 printWarn(string("removing orig file ")
443 + filename.latin1() 444 + filename.latin1()
444 + " failed!"); 445 + " failed!");
445 } 446 }
446 } 447 }
447 f.setName(filename); 448 f.setName(filename);
448 if (!f.open(IO_ReadWrite)) { 449 if (!f.open(IO_ReadWrite)) {
449 ret = e_openFile; 450 ret = e_openFile;
450 goto out_moveback; 451 goto out_moveback;
451 } 452 }
452 e = writeFileHeader(hashAlgo, hashAlgo, 453 e = writeFileHeader(hashAlgo, hashAlgo,
453 cryptAlgo, compress, 454 cryptAlgo, compress,
454 &currentPw, &f); 455 &currentPw, &f);
455 if (e == e_hashNotImpl) { 456 if (e == e_hashNotImpl) {
456 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 457 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
457 f.close(); 458 f.close();
458 ret = e_hashNotImpl; 459 ret = e_hashNotImpl;
459 goto out_moveback; 460 goto out_moveback;
460 } else if (e != e_success) { 461 } else if (e != e_success) {
461 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 462 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
462 f.close(); 463 f.close();
463 ret = e_writeHeader; 464 ret = e_writeHeader;
464 goto out_moveback; 465 goto out_moveback;
465 } 466 }
466 if (!serializeDta(&serialized)) { 467 if (!serializeDta(&serialized)) {
467 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 468 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
468 f.close(); 469 f.close();
469 ret = e_serializeDta; 470 ret = e_serializeDta;
470 goto out_moveback; 471 goto out_moveback;
471 } 472 }
472 e = writeDataHash(hashAlgo, &serialized, &f); 473 e = writeDataHash(hashAlgo, &serialized, &f);
473 if (e == e_hashNotImpl) { 474 if (e == e_hashNotImpl) {
474 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 475 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
475 f.close(); 476 f.close();
476 ret = e_hashNotImpl; 477 ret = e_hashNotImpl;
477 goto out_moveback; 478 goto out_moveback;
478 } else if (e != e_success) { 479 } else if (e != e_success) {
479 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 480 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
480 f.close(); 481 f.close();
481 ret = e_writeHeader; 482 ret = e_writeHeader;
482 goto out_moveback; 483 goto out_moveback;
483 } 484 }
484 if (!compressDta(&serialized, compress)) { 485 if (!compressDta(&serialized, compress)) {
485 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 486 printDebug("PwMDoc::saveDoc(): compressDta() failed");
486 f.close(); 487 f.close();
487 ret = e_enc; 488 ret = e_enc;
488 goto out_moveback; 489 goto out_moveback;
489 } 490 }
490 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo); 491 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
491 if (e == e_weakPw) { 492 if (e == e_weakPw) {
492 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 493 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
493 f.close(); 494 f.close();
494 ret = e_weakPw; 495 ret = e_weakPw;
495 goto out_moveback; 496 goto out_moveback;
496 } else if (e == e_cryptNotImpl) { 497 } else if (e == e_cryptNotImpl) {
497 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 498 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
498 f.close(); 499 f.close();
499 ret = e_cryptNotImpl; 500 ret = e_cryptNotImpl;
500 goto out_moveback; 501 goto out_moveback;
501 } else if (e != e_success) { 502 } else if (e != e_success) {
502 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 503 printDebug("PwMDoc::saveDoc(): encrypt() failed");
503 f.close(); 504 f.close();
504 ret = e_enc; 505 ret = e_enc;
505 goto out_moveback; 506 goto out_moveback;
506 } 507 }
507 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 508 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
508 f.close(); 509 f.close();
509#ifndef _WIN32_ 510#ifndef _WIN32_
510 if (chmod(filename.latin1(), 511 if (chmod(filename.latin1(),
511 conf()->confGlobFilePermissions())) { 512 conf()->confGlobFilePermissions())) {
512 printWarn(string("chmod failed: ") + strerror(errno)); 513 printWarn(string("chmod failed: ") + strerror(errno));
513 } 514 }
514#endif 515#endif
515 openDocList.edit(this, getTitle().latin1()); 516 openDocList.edit(this, getTitle().latin1());
516 if (wasDeepLocked) { 517 if (wasDeepLocked) {
517 /* Do _not_ save the data with the deepLock() 518 /* Do _not_ save the data with the deepLock()
518 * call, because this will recurse 519 * call, because this will recurse
519 * into saveDoc() 520 * into saveDoc()
520 */ 521 */
521 deepLock(true, false); 522 deepLock(true, false);
522 /* We don't check return value here, because 523 /* We don't check return value here, because
523 * it won't fail. See NOTE in deepLock() 524 * it won't fail. See NOTE in deepLock()
524 */ 525 */
525 } 526 }
526 if (tmpFileMoved != QString::null) { 527 if (tmpFileMoved != QString::null) {
527 // now remove the moved file. 528 // now remove the moved file.
528 if (!QFile::remove(tmpFileMoved)) { 529 if (!QFile::remove(tmpFileMoved)) {
529 printWarn(string("removing file ") 530 printWarn(string("removing file ")
530 + tmpFileMoved.latin1() 531 + tmpFileMoved.latin1()
531 + " failed!"); 532 + " failed!");
532 } 533 }
533 } 534 }
534 ret = e_success; 535 ret = e_success;
535 printDebug(string("writing file { name: ") 536 printDebug(string("writing file { name: ")
536 + filename.latin1() + " compress: " 537 + filename.latin1() + " compress: "
537 + tostr(static_cast<int>(compress)) + " cryptAlgo: " 538 + tostr(static_cast<int>(compress)) + " cryptAlgo: "
538 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " 539 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
539 + tostr(static_cast<int>(hashAlgo)) 540 + tostr(static_cast<int>(hashAlgo))
540 + " }"); 541 + " }");
541 goto out; 542 goto out;
542out_moveback: 543out_moveback:
543 if (tmpFileMoved != QString::null) { 544 if (tmpFileMoved != QString::null) {
544 if (copyFile(tmpFileMoved, filename)) { 545 if (copyFile(tmpFileMoved, filename)) {
545 if (!QFile::remove(tmpFileMoved)) { 546 if (!QFile::remove(tmpFileMoved)) {
546 printWarn(string("removing tmp file ") 547 printWarn(string("removing tmp file ")
547 + filename.latin1() 548 + filename.latin1()
548 + " failed!"); 549 + " failed!");
549 } 550 }
550 } else { 551 } else {
551 printWarn(string("couldn't copy file ") 552 printWarn(string("couldn't copy file ")
552 + tmpFileMoved.latin1() 553 + tmpFileMoved.latin1()
553 + " back to " 554 + " back to "
554 + filename.latin1()); 555 + filename.latin1());
555 } 556 }
556 } 557 }
557out: 558out:
558 return ret; 559 return ret;
559} 560}
560 561
561PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 562PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
562{ 563{
563 PWM_ASSERT(file); 564 PWM_ASSERT(file);
564 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 565 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
565 string decrypted, dataHash; 566 string decrypted, dataHash;
566 PwMerror ret; 567 PwMerror ret;
567 char cryptAlgo, dataHashType, compress; 568 char cryptAlgo, dataHashType, compress;
568 unsigned int headerLen; 569 unsigned int headerLen;
569 570
570 if (*file == "") 571 if (*file == "")
571 return e_readFile; 572 return e_readFile;
572 filename = *file; 573 filename = *file;
573 /* check if this file is already open. 574 /* check if this file is already open.
574 * This does not catch symlinks! 575 * This does not catch symlinks!
575 */ 576 */
576 if (!isDeepLocked()) { 577 if (!isDeepLocked()) {
577 if (getOpenDocList()->find(filename.latin1())) 578 if (getOpenDocList()->find(filename.latin1()))
578 return e_alreadyOpen; 579 return e_alreadyOpen;
579 } 580 }
580 QFile f(filename); 581 QFile f(filename);
581 582
582 if (openLocked == 2) { 583 if (openLocked == 2) {
583 // open deep-locked 584 // open deep-locked
584 if (!QFile::exists(filename)) 585 if (!QFile::exists(filename))
585 return e_openFile; 586 return e_openFile;
586 if (deepLock(true, false) != e_success) 587 if (deepLock(true, false) != e_success)
587 return e_openFile; 588 return e_openFile;
588 goto out_success; 589 goto out_success;
589 } 590 }
590 591
591 if (!f.open(IO_ReadOnly)) 592 if (!f.open(IO_ReadOnly))
592 return e_openFile; 593 return e_openFile;
593 594
594 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 595 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
595 &dataHashType, &dataHash, &f); 596 &dataHashType, &dataHash, &f);
596 if (ret != e_success) { 597 if (ret != e_success) {
597 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 598 printDebug("PwMDoc::openDoc(): checkHeader() failed");
598 f.close(); 599 f.close();
599 if (ret == e_wrongPw) { 600 if (ret == e_wrongPw) {
600 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 601 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
601 return ret; 602 return ret;
602 } else if (ret == e_noPw || 603 } else if (ret == e_noPw ||
603 ret == e_fileVer || 604 ret == e_fileVer ||
604 ret == e_fileFormat || 605 ret == e_fileFormat ||
605 ret == e_hashNotImpl) { 606 ret == e_hashNotImpl) {
606 return ret; 607 return ret;
607 } else 608 } else
608 return e_readFile; 609 return e_readFile;
609 } 610 }
610 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f); 611 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
611 if (ret == e_cryptNotImpl) { 612 if (ret == e_cryptNotImpl) {
612 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 613 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
613 f.close(); 614 f.close();
614 return e_cryptNotImpl; 615 return e_cryptNotImpl;
615 } else if (ret != e_success) { 616 } else if (ret != e_success) {
616 printDebug("PwMDoc::openDoc(): decrypt() failed"); 617 printDebug("PwMDoc::openDoc(): decrypt() failed");
617 f.close(); 618 f.close();
618 return e_readFile; 619 return e_readFile;
619 } 620 }
620 if (!decompressDta(&decrypted, compress)) { 621 if (!decompressDta(&decrypted, compress)) {
621 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 622 printDebug("PwMDoc::openDoc(): decompressDta() failed");
622 f.close(); 623 f.close();
623 return e_fileCorrupt; 624 return e_fileCorrupt;
624 } 625 }
625 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 626 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
626 if (ret == e_hashNotImpl) { 627 if (ret == e_hashNotImpl) {
627 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 628 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
628 f.close(); 629 f.close();
629 return e_hashNotImpl; 630 return e_hashNotImpl;
630 } else if (ret != e_success) { 631 } else if (ret != e_success) {
631 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 632 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
632 f.close(); 633 f.close();
633 return e_fileCorrupt; 634 return e_fileCorrupt;
634 } 635 }
635 if (!deSerializeDta(&decrypted, openLocked == 1)) { 636 if (!deSerializeDta(&decrypted, openLocked == 1)) {
636 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 637 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
637 f.close(); 638 f.close();
638 return e_readFile; 639 return e_readFile;
639 } 640 }
640 f.close(); 641 f.close();
641 timer()->start(DocTimer::id_mpwTimer); 642 timer()->start(DocTimer::id_mpwTimer);
642 timer()->start(DocTimer::id_autoLockTimer); 643 timer()->start(DocTimer::id_autoLockTimer);
643out_success: 644out_success:
644 openDocList.edit(this, getTitle().latin1()); 645 openDocList.edit(this, getTitle().latin1());
645 emit docOpened(this); 646 emit docOpened(this);
646 return e_success; 647 return e_success;
647} 648}
648 649
649PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 650PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
650 QString *pw, QFile *f) 651 QString *pw, QFile *f)
651{ 652{
652 PWM_ASSERT(pw); 653 PWM_ASSERT(pw);
653 PWM_ASSERT(f); 654 PWM_ASSERT(f);
654 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else 655 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
655 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion 656 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
656 //USPWM_ASSERT(listView); 657 //USPWM_ASSERT(listView);
657 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 658 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
658 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 659 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
659 return e_writeFile; 660 return e_writeFile;
660 } 661 }
661 if (f->putch(PWM_FILE_VER) == -1 || 662 if (f->putch(PWM_FILE_VER) == -1 ||
662 f->putch(keyHash) == -1 || 663 f->putch(keyHash) == -1 ||
663 f->putch(dataHash) == -1 || 664 f->putch(dataHash) == -1 ||
664 f->putch(crypt) == -1 || 665 f->putch(crypt) == -1 ||
665 f->putch(compress) == -1 || 666 f->putch(compress) == -1 ||
666 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 667 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
667 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 668 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
668 return e_writeFile; 669 return e_writeFile;
669 } 670 }
670 671
671 // write bytes of NUL-data. These bytes are reserved for future-use. 672 // write bytes of NUL-data. These bytes are reserved for future-use.
672 const int bufSize = 64; 673 const int bufSize = 64;
673 char tmp_buf[bufSize]; 674 char tmp_buf[bufSize];
674 memset(tmp_buf, 0x00, bufSize); 675 memset(tmp_buf, 0x00, bufSize);
675 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 676 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
676 return e_writeFile; 677 return e_writeFile;
677 678
678 switch (keyHash) { 679 switch (keyHash) {
679 case PWM_HASH_SHA1: { 680 case PWM_HASH_SHA1: {
680 const int hashlen = SHA1_HASH_LEN_BYTE; 681 const int hashlen = SHA1_HASH_LEN_BYTE;
681 Sha1 hash; 682 Sha1 hash;
682 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 683 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
683 string ret = hash.sha1_read(); 684 string ret = hash.sha1_read();
684 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 685 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
685 return e_writeFile; 686 return e_writeFile;
686 break; 687 break;
687 } 688 }
688 case PWM_HASH_SHA256: 689 case PWM_HASH_SHA256:
689 /*... fall through */ 690 /*... fall through */
690 case PWM_HASH_SHA384: 691 case PWM_HASH_SHA384:
691 case PWM_HASH_SHA512: 692 case PWM_HASH_SHA512:
692 case PWM_HASH_MD5: 693 case PWM_HASH_MD5:
693 case PWM_HASH_RMD160: 694 case PWM_HASH_RMD160:
694 case PWM_HASH_TIGER: 695 case PWM_HASH_TIGER:
695 { 696 {
696 if (!LibGCryptIf::available()) 697 if (!LibGCryptIf::available())
697 return e_hashNotImpl; 698 return e_hashNotImpl;
698 LibGCryptIf gc; 699 LibGCryptIf gc;
699 PwMerror err; 700 PwMerror err;
700 unsigned char *buf; 701 unsigned char *buf;
701 size_t hashLen; 702 size_t hashLen;
702 err = gc.hash(&buf, 703 err = gc.hash(&buf,
703 &hashLen, 704 &hashLen,
704 reinterpret_cast<const unsigned char *>(pw->latin1()), 705 reinterpret_cast<const unsigned char *>(pw->latin1()),
705 pw->length(), 706 pw->length(),
706 keyHash); 707 keyHash);
707 if (err != e_success) 708 if (err != e_success)
708 return e_hashNotImpl; 709 return e_hashNotImpl;
709 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 710 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
710 != static_cast<Q_LONG>(hashLen)) { 711 != static_cast<Q_LONG>(hashLen)) {
711 delete [] buf; 712 delete [] buf;
712 return e_hashNotImpl; 713 return e_hashNotImpl;
713 } 714 }
714 delete [] buf; 715 delete [] buf;
715 break; 716 break;
716 } 717 }
717 default: { 718 default: {
718 return e_hashNotImpl; 719 return e_hashNotImpl;
719 } } 720 } }
720 return e_success; 721 return e_success;
721} 722}
722 723
723PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 724PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
724 unsigned int *headerLength, char *dataHashType, 725 unsigned int *headerLength, char *dataHashType,
725 string *dataHash, QFile *f) 726 string *dataHash, QFile *f)
726{ 727{
727 PWM_ASSERT(cryptAlgo); 728 PWM_ASSERT(cryptAlgo);
728 PWM_ASSERT(pw); 729 PWM_ASSERT(pw);
729 PWM_ASSERT(headerLength); 730 PWM_ASSERT(headerLength);
730 PWM_ASSERT(dataHashType); 731 PWM_ASSERT(dataHashType);
731 PWM_ASSERT(dataHash); 732 PWM_ASSERT(dataHash);
732 PWM_ASSERT(f); 733 PWM_ASSERT(f);
733 int tmpRet; 734 int tmpRet;
734 // check "magic" header 735 // check "magic" header
735 const char magicHdr[] = FILE_ID_HEADER; 736 const char magicHdr[] = FILE_ID_HEADER;
736 const int hdrLen = array_size(magicHdr) - 1; 737 const int hdrLen = array_size(magicHdr) - 1;
737 char tmp[hdrLen]; 738 char tmp[hdrLen];
738 if (f->readBlock(tmp, hdrLen) != hdrLen) 739 if (f->readBlock(tmp, hdrLen) != hdrLen)
739 return e_readFile; 740 return e_readFile;
740 if (memcmp(tmp, magicHdr, hdrLen) != 0) 741 if (memcmp(tmp, magicHdr, hdrLen) != 0)
741 return e_fileFormat; 742 return e_fileFormat;
742 // read and check file ver 743 // read and check file ver
743 int fileV = f->getch(); 744 int fileV = f->getch();
744 if (fileV == -1) 745 if (fileV == -1)
745 return e_fileFormat; 746 return e_fileFormat;
746 if (fileV != PWM_FILE_VER) 747 if (fileV != PWM_FILE_VER)
747 return e_fileVer; 748 return e_fileVer;
748 // read hash hash type 749 // read hash hash type
749 int keyHash = f->getch(); 750 int keyHash = f->getch();
750 if (keyHash == -1) 751 if (keyHash == -1)
751 return e_fileFormat; 752 return e_fileFormat;
752 // read data hash type 753 // read data hash type
753 tmpRet = f->getch(); 754 tmpRet = f->getch();
754 if (tmpRet == -1) 755 if (tmpRet == -1)
755 return e_fileFormat; 756 return e_fileFormat;
756 *dataHashType = tmpRet; 757 *dataHashType = tmpRet;
757 // read crypt algo 758 // read crypt algo
758 tmpRet = f->getch(); 759 tmpRet = f->getch();
759 if (tmpRet == -1) 760 if (tmpRet == -1)
760 return e_fileFormat; 761 return e_fileFormat;
761 *cryptAlgo = tmpRet; 762 *cryptAlgo = tmpRet;
762 // get compression-algo 763 // get compression-algo
763 tmpRet = f->getch(); 764 tmpRet = f->getch();
764 if (tmpRet == -1) 765 if (tmpRet == -1)
765 return e_fileFormat; 766 return e_fileFormat;
766 *compress = tmpRet; 767 *compress = tmpRet;
767 // get the MPW-flag 768 // get the MPW-flag
768 int mpw_flag = f->getch(); 769 int mpw_flag = f->getch();
769 if (mpw_flag == -1) 770 if (mpw_flag == -1)
770 return e_fileFormat; 771 return e_fileFormat;
771 if (mpw_flag == 0x01) 772 if (mpw_flag == 0x01)
772 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 773 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
773 else 774 else
774 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 775 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
775 // skip the "RESERVED"-bytes 776 // skip the "RESERVED"-bytes
776 if (!(f->at(f->at() + 64))) 777 if (!(f->at(f->at() + 64)))
777 return e_fileFormat; 778 return e_fileFormat;
778 779
779 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 780 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
780 if (*pw == "") { 781 if (*pw == "") {
781 /* the user didn't give a master-password 782 /* the user didn't give a master-password
782 * or didn't insert a chipcard 783 * or didn't insert a chipcard
783 */ 784 */
784 return e_noPw; 785 return e_noPw;
785 } 786 }
786 // verify key-hash 787 // verify key-hash
787 switch (keyHash) { 788 switch (keyHash) {
788 case PWM_HASH_SHA1: { 789 case PWM_HASH_SHA1: {
789 // read hash from header 790 // read hash from header
790 const int hashLen = SHA1_HASH_LEN_BYTE; 791 const int hashLen = SHA1_HASH_LEN_BYTE;
791 string readHash; 792 string readHash;
792 int i; 793 int i;
793 for (i = 0; i < hashLen; ++i) 794 for (i = 0; i < hashLen; ++i)
794 readHash.push_back(f->getch()); 795 readHash.push_back(f->getch());
795 Sha1 hash; 796 Sha1 hash;
796 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 797 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
797 string ret = hash.sha1_read(); 798 string ret = hash.sha1_read();
798 if (ret != readHash) 799 if (ret != readHash)
799 return e_wrongPw;// hash doesn't match (wrong key) 800 return e_wrongPw;// hash doesn't match (wrong key)
800 break; 801 break;
801 } 802 }
802 case PWM_HASH_SHA256: 803 case PWM_HASH_SHA256:
803 /*... fall through */ 804 /*... fall through */
804 case PWM_HASH_SHA384: 805 case PWM_HASH_SHA384:
805 case PWM_HASH_SHA512: 806 case PWM_HASH_SHA512:
806 case PWM_HASH_MD5: 807 case PWM_HASH_MD5:
807 case PWM_HASH_RMD160: 808 case PWM_HASH_RMD160:
808 case PWM_HASH_TIGER: { 809 case PWM_HASH_TIGER: {
809 if (!LibGCryptIf::available()) 810 if (!LibGCryptIf::available())
810 return e_hashNotImpl; 811 return e_hashNotImpl;
811 LibGCryptIf gc; 812 LibGCryptIf gc;
812 PwMerror err; 813 PwMerror err;
813 unsigned char *buf; 814 unsigned char *buf;
814 size_t hashLen; 815 size_t hashLen;
815 err = gc.hash(&buf, 816 err = gc.hash(&buf,
816 &hashLen, 817 &hashLen,
817 reinterpret_cast<const unsigned char *>(pw->latin1()), 818 reinterpret_cast<const unsigned char *>(pw->latin1()),
818 pw->length(), 819 pw->length(),
819 keyHash); 820 keyHash);
820 if (err != e_success) 821 if (err != e_success)
821 return e_hashNotImpl; 822 return e_hashNotImpl;
822 string calcHash(reinterpret_cast<const char *>(buf), 823 string calcHash(reinterpret_cast<const char *>(buf),
823 static_cast<string::size_type>(hashLen)); 824 static_cast<string::size_type>(hashLen));
824 delete [] buf; 825 delete [] buf;
825 // read hash from header 826 // read hash from header
826 string readHash; 827 string readHash;
827 size_t i; 828 size_t i;
828 for (i = 0; i < hashLen; ++i) 829 for (i = 0; i < hashLen; ++i)
829 readHash.push_back(f->getch()); 830 readHash.push_back(f->getch());
830 if (calcHash != readHash) 831 if (calcHash != readHash)
831 return e_wrongPw;// hash doesn't match (wrong key) 832 return e_wrongPw;// hash doesn't match (wrong key)
832 break; 833 break;
833 } 834 }
834 default: { 835 default: {
835 return e_hashNotImpl; 836 return e_hashNotImpl;
836 } } 837 } }
837 // read the data-hash from the file 838 // read the data-hash from the file
838 unsigned int hashLen, i; 839 unsigned int hashLen, i;
839 switch (*dataHashType) { 840 switch (*dataHashType) {
840 case PWM_HASH_SHA1: 841 case PWM_HASH_SHA1:
841 hashLen = SHA1_HASH_LEN_BYTE; 842 hashLen = SHA1_HASH_LEN_BYTE;
842 break; 843 break;
843 case PWM_HASH_SHA256: 844 case PWM_HASH_SHA256:
844 /*... fall through */ 845 /*... fall through */
845 case PWM_HASH_SHA384: 846 case PWM_HASH_SHA384:
846 case PWM_HASH_SHA512: 847 case PWM_HASH_SHA512:
847 case PWM_HASH_MD5: 848 case PWM_HASH_MD5:
848 case PWM_HASH_RMD160: 849 case PWM_HASH_RMD160:
849 case PWM_HASH_TIGER: { 850 case PWM_HASH_TIGER: {
850 if (!LibGCryptIf::available()) 851 if (!LibGCryptIf::available())
851 return e_hashNotImpl; 852 return e_hashNotImpl;
852 LibGCryptIf gc; 853 LibGCryptIf gc;
853 hashLen = gc.hashLength(*dataHashType); 854 hashLen = gc.hashLength(*dataHashType);
854 if (hashLen == 0) 855 if (hashLen == 0)
855 return e_hashNotImpl; 856 return e_hashNotImpl;
856 break; 857 break;
857 } 858 }
858 default: 859 default:
859 return e_hashNotImpl; 860 return e_hashNotImpl;
860 } 861 }
861 *dataHash = ""; 862 *dataHash = "";
862 for (i = 0; i < hashLen; ++i) { 863 for (i = 0; i < hashLen; ++i) {
863 tmpRet = f->getch(); 864 tmpRet = f->getch();
864 if (tmpRet == -1) 865 if (tmpRet == -1)
865 return e_fileFormat; 866 return e_fileFormat;
866 dataHash->push_back(static_cast<char>(tmpRet)); 867 dataHash->push_back(static_cast<char>(tmpRet));
867 } 868 }
868 *headerLength = f->at(); 869 *headerLength = f->at();
869#ifndef PWM_EMBEDDED 870#ifndef PWM_EMBEDDED
870 printDebug(string("opening file { compress: ") 871 printDebug(string("opening file { compress: ")
871 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 872 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
872 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 873 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
873 + tostr(static_cast<int>(keyHash)) 874 + tostr(static_cast<int>(keyHash))
874 + " }"); 875 + " }");
875#else 876#else
876 printDebug(string("opening file { compress: ") 877 printDebug(string("opening file { compress: ")
877 + tostr((int)(*compress)) + " cryptAlgo: " 878 + tostr((int)(*compress)) + " cryptAlgo: "
878 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 879 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
879 + tostr((int)(keyHash)) 880 + tostr((int)(keyHash))
880 + " }"); 881 + " }");
881#endif 882#endif
882 883
883 return e_success; 884 return e_success;
884} 885}
885 886
886PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 887PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
887{ 888{
888 PWM_ASSERT(d); 889 PWM_ASSERT(d);
889 PWM_ASSERT(f); 890 PWM_ASSERT(f);
890 891
891 switch (dataHash) { 892 switch (dataHash) {
892 case PWM_HASH_SHA1: { 893 case PWM_HASH_SHA1: {
893 const int hashLen = SHA1_HASH_LEN_BYTE; 894 const int hashLen = SHA1_HASH_LEN_BYTE;
894 Sha1 h; 895 Sha1 h;
895 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 896 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
896 string hRet = h.sha1_read(); 897 string hRet = h.sha1_read();
897 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 898 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
898 return e_writeFile; 899 return e_writeFile;
899 break; 900 break;
900 } 901 }
901 case PWM_HASH_SHA256: 902 case PWM_HASH_SHA256:
902 /*... fall through */ 903 /*... fall through */
903 case PWM_HASH_SHA384: 904 case PWM_HASH_SHA384:
904 case PWM_HASH_SHA512: 905 case PWM_HASH_SHA512:
905 case PWM_HASH_MD5: 906 case PWM_HASH_MD5:
906 case PWM_HASH_RMD160: 907 case PWM_HASH_RMD160:
907 case PWM_HASH_TIGER: { 908 case PWM_HASH_TIGER: {
908 if (!LibGCryptIf::available()) 909 if (!LibGCryptIf::available())
909 return e_hashNotImpl; 910 return e_hashNotImpl;
910 LibGCryptIf gc; 911 LibGCryptIf gc;
911 PwMerror err; 912 PwMerror err;
912 unsigned char *buf; 913 unsigned char *buf;
913 size_t hashLen; 914 size_t hashLen;
914 err = gc.hash(&buf, 915 err = gc.hash(&buf,
915 &hashLen, 916 &hashLen,
916 reinterpret_cast<const unsigned char *>(d->c_str()), 917 reinterpret_cast<const unsigned char *>(d->c_str()),
917 d->size(), 918 d->size(),
918 dataHash); 919 dataHash);
919 if (err != e_success) 920 if (err != e_success)
920 return e_hashNotImpl; 921 return e_hashNotImpl;
921 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 922 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
922 != static_cast<Q_LONG>(hashLen)) { 923 != static_cast<Q_LONG>(hashLen)) {
923 delete [] buf; 924 delete [] buf;
924 return e_hashNotImpl; 925 return e_hashNotImpl;
925 } 926 }
926 delete [] buf; 927 delete [] buf;
927 break; 928 break;
928 } 929 }
929 default: { 930 default: {
930 return e_hashNotImpl; 931 return e_hashNotImpl;
931 } } 932 } }
932 933
933 return e_success; 934 return e_success;
934} 935}
935 936
936bool PwMDoc::backupFile(const QString &filePath) 937bool PwMDoc::backupFile(const QString &filePath)
937{ 938{
938 QFileInfo fi(filePath); 939 QFileInfo fi(filePath);
939 if (!fi.exists()) 940 if (!fi.exists())
940 return true; // Yes, true is correct. 941 return true; // Yes, true is correct.
941 QString pathOnly(fi.dirPath(true)); 942 QString pathOnly(fi.dirPath(true));
942 QString nameOnly(fi.fileName()); 943 QString nameOnly(fi.fileName());
943 QString backupPath = pathOnly 944 QString backupPath = pathOnly
944 + "/~" 945 + "/~"
945 + nameOnly 946 + nameOnly
946 + ".backup"; 947 + ".backup";
947 return copyFile(filePath, backupPath); 948 return copyFile(filePath, backupPath);
948} 949}
949 950
950bool PwMDoc::copyFile(const QString &src, const QString &dst) 951bool PwMDoc::copyFile(const QString &src, const QString &dst)
951{ 952{
952 QFileInfo fi(src); 953 QFileInfo fi(src);
953 if (!fi.exists()) 954 if (!fi.exists())
954 return false; 955 return false;
955 if (QFile::exists(dst)) { 956 if (QFile::exists(dst)) {
956 if (!QFile::remove(dst)) 957 if (!QFile::remove(dst))
957 return false; 958 return false;
958 } 959 }
959 QFile srcFd(src); 960 QFile srcFd(src);
960 if (!srcFd.open(IO_ReadOnly)) 961 if (!srcFd.open(IO_ReadOnly))
961 return false; 962 return false;
962 QFile dstFd(dst); 963 QFile dstFd(dst);
963 if (!dstFd.open(IO_ReadWrite)) { 964 if (!dstFd.open(IO_ReadWrite)) {
964 srcFd.close(); 965 srcFd.close();
965 return false; 966 return false;
966 } 967 }
967 const int tmpBuf_size = 512; 968 const int tmpBuf_size = 512;
968 char tmpBuf[tmpBuf_size]; 969 char tmpBuf[tmpBuf_size];
969 Q_LONG bytesRead, bytesWritten; 970 Q_LONG bytesRead, bytesWritten;
970 971
971 while (!srcFd.atEnd()) { 972 while (!srcFd.atEnd()) {
972 bytesRead = srcFd.readBlock(tmpBuf, 973 bytesRead = srcFd.readBlock(tmpBuf,
973 static_cast<Q_ULONG>(tmpBuf_size)); 974 static_cast<Q_ULONG>(tmpBuf_size));
974 if (bytesRead == -1) { 975 if (bytesRead == -1) {
975 srcFd.close(); 976 srcFd.close();
976 dstFd.close(); 977 dstFd.close();
977 return false; 978 return false;
978 } 979 }
979 bytesWritten = dstFd.writeBlock(tmpBuf, 980 bytesWritten = dstFd.writeBlock(tmpBuf,
980 static_cast<Q_ULONG>(bytesRead)); 981 static_cast<Q_ULONG>(bytesRead));
981 if (bytesWritten != bytesRead) { 982 if (bytesWritten != bytesRead) {
982 srcFd.close(); 983 srcFd.close();
983 dstFd.close(); 984 dstFd.close();
984 return false; 985 return false;
985 } 986 }
986 } 987 }
987 srcFd.close(); 988 srcFd.close();
988 dstFd.close(); 989 dstFd.close();
989 return true; 990 return true;
990} 991}
991 992
992PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 993PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
993 bool dontFlagDirty, bool updateMeta) 994 bool dontFlagDirty, bool updateMeta)
994{ 995{
995 PWM_ASSERT(d); 996 PWM_ASSERT(d);
996 unsigned int cat = 0; 997 unsigned int cat = 0;
997 998
998 if (isDeepLocked()) { 999 if (isDeepLocked()) {
999 PwMerror ret; 1000 PwMerror ret;
1000 ret = deepLock(false); 1001 ret = deepLock(false);
1001 if (ret != e_success) 1002 if (ret != e_success)
1002 return e_lock; 1003 return e_lock;
1003 } 1004 }
1004 1005
1005 addCategory(category, &cat); 1006 addCategory(category, &cat);
1006 1007
1007 if (numEntries(category) >= maxEntries) 1008 if (numEntries(category) >= maxEntries)
1008 return e_maxAllowedEntr; 1009 return e_maxAllowedEntr;
1009 1010
1010 vector<unsigned int> foundPositions; 1011 vector<unsigned int> foundPositions;
1011 /* historically this was: 1012 /* historically this was:
1012 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 1013 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
1013 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 1014 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
1014 * But for now we only search in desc. 1015 * But for now we only search in desc.
1015 * That's a tweak to be KWallet compatible. But it should not add 1016 * That's a tweak to be KWallet compatible. But it should not add
1016 * usability-drop onto PwManager, does it? 1017 * usability-drop onto PwManager, does it?
1017 * (And yes, "int" was a bug. Correct is "unsigned int") 1018 * (And yes, "int" was a bug. Correct is "unsigned int")
1018 */ 1019 */
1019 const unsigned int searchIn = SEARCH_IN_DESC; 1020 const unsigned int searchIn = SEARCH_IN_DESC;
1020 findEntry(cat, *d, searchIn, &foundPositions, true); 1021 findEntry(cat, *d, searchIn, &foundPositions, true);
1021 if (foundPositions.size()) { 1022 if (foundPositions.size()) {
1022 // DOH! We found this entry. 1023 // DOH! We found this entry.
1023 return e_entryExists; 1024 return e_entryExists;
1024 } 1025 }
1025 1026
1026 d->listViewPos = -1; 1027 d->listViewPos = -1;
1027 d->lockStat = conf()->confGlobNewEntrLockStat(); 1028 d->lockStat = conf()->confGlobNewEntrLockStat();
1028 if (updateMeta) { 1029 if (updateMeta) {
1029 d->meta.create = QDateTime::currentDateTime(); 1030 d->meta.create = QDateTime::currentDateTime();
1030 d->meta.update = d->meta.create; 1031 d->meta.update = d->meta.create;
1031 } 1032 }
1032 dti.dta[cat].d.push_back(*d); 1033 dti.dta[cat].d.push_back(*d);
1033 1034
1034 delAllEmptyCat(true); 1035 delAllEmptyCat(true);
1035 1036
1036 if (!dontFlagDirty) 1037 if (!dontFlagDirty)
1037 flagDirty(); 1038 flagDirty();
1038 return e_success; 1039 return e_success;
1039} 1040}
1040 1041
1041PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 1042PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
1042 bool checkIfExist) 1043 bool checkIfExist)
1043{ 1044{
1044 if (isDeepLocked()) { 1045 if (isDeepLocked()) {
1045 PwMerror ret; 1046 PwMerror ret;
1046 ret = deepLock(false); 1047 ret = deepLock(false);
1047 if (ret != e_success) 1048 if (ret != e_success)
1048 return e_lock; 1049 return e_lock;
1049 } 1050 }
1050 if (checkIfExist) { 1051 if (checkIfExist) {
1051 if (findCategory(category, categoryIndex)) 1052 if (findCategory(category, categoryIndex))
1052 return e_categoryExists; 1053 return e_categoryExists;
1053 } 1054 }
1054 PwMCategoryItem item; 1055 PwMCategoryItem item;
1055 //US ENH: clear item to initialize with default values, or create a constructor 1056 //US ENH: clear item to initialize with default values, or create a constructor
1056 item.clear(); 1057 item.clear();
1057 1058
1058 item.name = category.latin1(); 1059 item.name = category.latin1();
1059 dti.dta.push_back(item); 1060 dti.dta.push_back(item);
1060 if (categoryIndex) 1061 if (categoryIndex)
1061 *categoryIndex = dti.dta.size() - 1; 1062 *categoryIndex = dti.dta.size() - 1;
1062 return e_success; 1063 return e_success;
1063} 1064}
1064 1065
1065bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1066bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1066{ 1067{
1067 unsigned int cat = 0; 1068 unsigned int cat = 0;
1068 1069
1069 if (!findCategory(category, &cat)) { 1070 if (!findCategory(category, &cat)) {
1070 BUG(); 1071 BUG();
1071 return false; 1072 return false;
1072 } 1073 }
1073 1074
1074 return delEntry(cat, index, dontFlagDirty); 1075 return delEntry(cat, index, dontFlagDirty);
1075} 1076}
1076 1077
1077bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1078bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1078{ 1079{
1079 if (isDeepLocked()) 1080 if (isDeepLocked())
1080 return false; 1081 return false;
1081 if (index > dti.dta[category].d.size() - 1) 1082 if (index > dti.dta[category].d.size() - 1)
1082 return false; 1083 return false;
1083 getDataChangedLock(); 1084 getDataChangedLock();
1084 if (!lockAt(category, index, false)) { 1085 if (!lockAt(category, index, false)) {
1085 putDataChangedLock(); 1086 putDataChangedLock();
1086 return false; 1087 return false;
1087 } 1088 }
1088 putDataChangedLock(); 1089 putDataChangedLock();
1089 int lvPos = dti.dta[category].d[index].listViewPos; 1090 int lvPos = dti.dta[category].d[index].listViewPos;
1090 1091
1091 // delete entry 1092 // delete entry
1092 dti.dta[category].d.erase(dti.dta[category].d.begin() + index); 1093 dti.dta[category].d.erase(dti.dta[category].d.begin() + index);
1093 1094
1094 unsigned int i, entries = numEntries(category); 1095 unsigned int i, entries = numEntries(category);
1095 if (!entries) { 1096 if (!entries) {
1096 // no more entries in this category, so 1097 // no more entries in this category, so
1097 // we can delete it, too. 1098 // we can delete it, too.
1098 BUG_ON(!delCategory(category)); 1099 BUG_ON(!delCategory(category));
1099 // delCategory() flags it dirty, so we need not to do so. 1100 // delCategory() flags it dirty, so we need not to do so.
1100 return true; 1101 return true;
1101 } 1102 }
1102 for (i = 0; i < entries; ++i) { 1103 for (i = 0; i < entries; ++i) {
1103 // decrement all listViewPositions that are greater than the deleted. 1104 // decrement all listViewPositions that are greater than the deleted.
1104 if (dti.dta[category].d[i].listViewPos > lvPos) 1105 if (dti.dta[category].d[i].listViewPos > lvPos)
1105 --dti.dta[category].d[i].listViewPos; 1106 --dti.dta[category].d[i].listViewPos;
1106 } 1107 }
1107 1108
1108 if (!dontFlagDirty) 1109 if (!dontFlagDirty)
1109 flagDirty(); 1110 flagDirty();
1110 return true; 1111 return true;
1111} 1112}
1112 1113
1113bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, 1114bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory,
1114 unsigned int index, PwMDataItem *d, bool updateMeta) 1115 unsigned int index, PwMDataItem *d, bool updateMeta)
1115{ 1116{
1116 PWM_ASSERT(d); 1117 PWM_ASSERT(d);
1117 unsigned int oldCat = 0; 1118 unsigned int oldCat = 0;
1118 1119
1119 if (!findCategory(oldCategory, &oldCat)) { 1120 if (!findCategory(oldCategory, &oldCat)) {
1120 BUG(); 1121 BUG();
1121 return false; 1122 return false;
1122 } 1123 }
1123 1124
1124 return editEntry(oldCat, newCategory, index, d, updateMeta); 1125 return editEntry(oldCat, newCategory, index, d, updateMeta);
1125} 1126}
1126 1127
1127bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, 1128bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory,
1128 unsigned int index, PwMDataItem *d, bool updateMeta) 1129 unsigned int index, PwMDataItem *d, bool updateMeta)
1129{ 1130{
1130 if (isDeepLocked()) 1131 if (isDeepLocked())
1131 return false; 1132 return false;
1132 if (updateMeta) { 1133 if (updateMeta) {
1133 d->meta.update = QDateTime::currentDateTime(); 1134 d->meta.update = QDateTime::currentDateTime();
1134 if (d->meta.create.isNull()) { 1135 if (d->meta.create.isNull()) {
1135 d->meta.create = d->meta.update; 1136 d->meta.create = d->meta.update;
1136 } 1137 }
1137 } 1138 }
1138 if (dti.dta[oldCategory].name != newCategory.latin1()) { 1139 if (dti.dta[oldCategory].name != newCategory.latin1()) {
1139 // the user changed the category. 1140 // the user changed the category.
1140 PwMerror ret; 1141 PwMerror ret;
1141 d->rev = 0; 1142 d->rev = 0;
1142 ret = addEntry(newCategory, d, true, false); 1143 ret = addEntry(newCategory, d, true, false);
1143 if (ret != e_success) 1144 if (ret != e_success)
1144 return false; 1145 return false;
1145 if (!delEntry(oldCategory, index, true)) 1146 if (!delEntry(oldCategory, index, true))
1146 return false; 1147 return false;
1147 } else { 1148 } else {
1148 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter. 1149 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter.
1149 dti.dta[oldCategory].d[index] = *d; 1150 dti.dta[oldCategory].d[index] = *d;
1150 } 1151 }
1151 flagDirty(); 1152 flagDirty();
1152 return true; 1153 return true;
1153} 1154}
1154 1155
1155unsigned int PwMDoc::numEntries(const QString &category) 1156unsigned int PwMDoc::numEntries(const QString &category)
1156{ 1157{
1157 unsigned int cat = 0; 1158 unsigned int cat = 0;
1158 1159
1159 if (!findCategory(category, &cat)) { 1160 if (!findCategory(category, &cat)) {
1160 BUG(); 1161 BUG();
1161 return 0; 1162 return 0;
1162 } 1163 }
1163 1164
1164 return numEntries(cat); 1165 return numEntries(cat);
1165} 1166}
1166 1167
1167bool PwMDoc::serializeDta(string *d) 1168bool PwMDoc::serializeDta(string *d)
1168{ 1169{
1169 PWM_ASSERT(d); 1170 PWM_ASSERT(d);
1170 Serializer ser; 1171 Serializer ser;
1171 if (!ser.serialize(dti)) 1172 if (!ser.serialize(dti))
1172 return false; 1173 return false;
1173 d->assign(ser.getXml()); 1174 d->assign(ser.getXml());
1174 if (!d->size()) 1175 if (!d->size())
1175 return false; 1176 return false;
1176 return true; 1177 return true;
1177} 1178}
1178 1179
1179bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked) 1180bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked)
1180{ 1181{
1181 PWM_ASSERT(d); 1182 PWM_ASSERT(d);
1182#ifndef PWM_EMBEDDED 1183#ifndef PWM_EMBEDDED
1183 try { 1184 try {
1184 1185
1185 Serializer ser(d->c_str()); 1186 Serializer ser(d->c_str());
1186 ser.setDefaultLockStat(entriesLocked); 1187 ser.setDefaultLockStat(entriesLocked);
1187 if (!ser.deSerialize(&dti)) 1188 if (!ser.deSerialize(&dti))
1188 return false; 1189 return false;
1189 } catch (PwMException) { 1190 } catch (PwMException) {
1190 return false; 1191 return false;
1191 } 1192 }
1192#else 1193#else
1193 Serializer ser(d->c_str()); 1194 Serializer ser(d->c_str());
1194 ser.setDefaultLockStat(entriesLocked); 1195 ser.setDefaultLockStat(entriesLocked);
1195 if (!ser.deSerialize(&dti)) 1196 if (!ser.deSerialize(&dti))
1196 return false; 1197 return false;
1197#endif 1198#endif
1198 1199
1199 emitDataChanged(this); 1200 emitDataChanged(this);
1200 return true; 1201 return true;
1201} 1202}
1202 1203
1203bool PwMDoc::getEntry(const QString &category, unsigned int index, 1204bool PwMDoc::getEntry(const QString &category, unsigned int index,
1204 PwMDataItem * d, bool unlockIfLocked) 1205 PwMDataItem * d, bool unlockIfLocked)
1205{ 1206{
1206 PWM_ASSERT(d); 1207 PWM_ASSERT(d);
1207 unsigned int cat = 0; 1208 unsigned int cat = 0;
1208 1209
1209 if (!findCategory(category, &cat)) { 1210 if (!findCategory(category, &cat)) {
1210 BUG(); 1211 BUG();
1211 return false; 1212 return false;
1212 } 1213 }
1213 1214
1214 return getEntry(cat, index, d, unlockIfLocked); 1215 return getEntry(cat, index, d, unlockIfLocked);
1215} 1216}
1216 1217
1217bool PwMDoc::getEntry(unsigned int category, unsigned int index, 1218bool PwMDoc::getEntry(unsigned int category, unsigned int index,
1218 PwMDataItem *d, bool unlockIfLocked) 1219 PwMDataItem *d, bool unlockIfLocked)
1219{ 1220{
1220 if (index > dti.dta[category].d.size() - 1) 1221 if (index > dti.dta[category].d.size() - 1)
1221 return false; 1222 return false;
1222 1223
1223 bool locked = isLocked(category, index); 1224 bool locked = isLocked(category, index);
1224 if (locked) { 1225 if (locked) {
1225 /* this entry is locked. We don't return a password, 1226 /* this entry is locked. We don't return a password,
1226 * until it's unlocked by the user by inserting 1227 * until it's unlocked by the user by inserting
1227 * chipcard or entering the mpw 1228 * chipcard or entering the mpw
1228 */ 1229 */
1229 if (unlockIfLocked) { 1230 if (unlockIfLocked) {
1230 if (!lockAt(category, index, false)) { 1231 if (!lockAt(category, index, false)) {
1231 return false; 1232 return false;
1232 } 1233 }
1233 locked = false; 1234 locked = false;
1234 } 1235 }
1235 } 1236 }
1236 1237
1237 *d = dti.dta[category].d[index]; 1238 *d = dti.dta[category].d[index];
1238 if (locked) 1239 if (locked)
1239 d->pw = LOCKED_STRING.latin1(); 1240 d->pw = LOCKED_STRING.latin1();
1240 1241
1241 return true; 1242 return true;
1242} 1243}
1243 1244
1244PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, 1245PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos,
1245 string *foundComment) 1246 string *foundComment)
1246{ 1247{
1247 PWM_ASSERT(foundComment); 1248 PWM_ASSERT(foundComment);
1248 unsigned int cat = 0; 1249 unsigned int cat = 0;
1249 1250
1250 if (!findCategory(category, &cat)) 1251 if (!findCategory(category, &cat))
1251 return e_invalidArg; 1252 return e_invalidArg;
1252 1253
1253 unsigned int i, entries = numEntries(cat); 1254 unsigned int i, entries = numEntries(cat);
1254 for (i = 0; i < entries; ++i) { 1255 for (i = 0; i < entries; ++i) {
1255 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1256 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1256 *foundComment = dti.dta[cat].d[i].comment; 1257 *foundComment = dti.dta[cat].d[i].comment;
1257 if (dti.dta[cat].d[i].binary) 1258 if (dti.dta[cat].d[i].binary)
1258 return e_binEntry; 1259 return e_binEntry;
1259 return e_normalEntry; 1260 return e_normalEntry;
1260 } 1261 }
1261 } 1262 }
1262 BUG(); 1263 BUG();
1263 return e_generic; 1264 return e_generic;
1264} 1265}
1265 1266
1266bool PwMDoc::compressDta(string *d, char algo) 1267bool PwMDoc::compressDta(string *d, char algo)
1267{ 1268{
1268 PWM_ASSERT(d); 1269 PWM_ASSERT(d);
1269 switch (algo) { 1270 switch (algo) {
1270 case PWM_COMPRESS_GZIP: { 1271 case PWM_COMPRESS_GZIP: {
1271 CompressGzip comp; 1272 CompressGzip comp;
1272 return comp.compress(d); 1273 return comp.compress(d);
1273 } 1274 }
1274#ifndef PWM_EMBEDDED 1275#ifndef PWM_EMBEDDED
1275 case PWM_COMPRESS_BZIP2: { 1276 case PWM_COMPRESS_BZIP2: {
1276 CompressBzip2 comp; 1277 CompressBzip2 comp;
1277 return comp.compress(d); 1278 return comp.compress(d);
1278 } 1279 }
1279#endif 1280#endif
1280 case PWM_COMPRESS_NONE: { 1281 case PWM_COMPRESS_NONE: {
1281 return true; 1282 return true;
1282 } default: { 1283 } default: {
1283 BUG(); 1284 BUG();
1284 } 1285 }
1285 } 1286 }
1286 return false; 1287 return false;
1287} 1288}
1288 1289
1289bool PwMDoc::decompressDta(string *d, char algo) 1290bool PwMDoc::decompressDta(string *d, char algo)
1290{ 1291{
1291 PWM_ASSERT(d); 1292 PWM_ASSERT(d);
1292 switch (algo) { 1293 switch (algo) {
1293 case PWM_COMPRESS_GZIP: { 1294 case PWM_COMPRESS_GZIP: {
1294 CompressGzip comp; 1295 CompressGzip comp;
1295 return comp.decompress(d); 1296 return comp.decompress(d);
1296 } 1297 }
1297#ifndef PWM_EMBEDDED 1298#ifndef PWM_EMBEDDED
1298 case PWM_COMPRESS_BZIP2: { 1299 case PWM_COMPRESS_BZIP2: {
1299 CompressBzip2 comp; 1300 CompressBzip2 comp;
1300 return comp.decompress(d); 1301 return comp.decompress(d);
1301 } 1302 }
1302#endif 1303#endif
1303 case PWM_COMPRESS_NONE: { 1304 case PWM_COMPRESS_NONE: {
1304 return true; 1305 return true;
1305 } 1306 }
1306 } 1307 }
1307 return false; 1308 return false;
1308} 1309}
1309 1310
1310PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo, 1311PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo,
1311 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1312 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1312) 1313)
1313{ 1314{
1314 PWM_ASSERT(d); 1315 PWM_ASSERT(d);
1315 PWM_ASSERT(pw); 1316 PWM_ASSERT(pw);
1316 PWM_ASSERT(f); 1317 PWM_ASSERT(f);
1317 1318
1318 size_t encSize; 1319 size_t encSize;
1319 byte *encrypted = 0; 1320 byte *encrypted = 0;
1320 1321
1321 switch (algo) { 1322 switch (algo) {
1322 case PWM_CRYPT_BLOWFISH: { 1323 case PWM_CRYPT_BLOWFISH: {
1323 Blowfish::padNull(d); 1324 Blowfish::padNull(d);
1324 encSize = d->length(); 1325 encSize = d->length();
1325 encrypted = new byte[encSize]; 1326 encrypted = new byte[encSize];
1326 Blowfish bf; 1327 Blowfish bf;
1327 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1328 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1328 delete [] encrypted; 1329 delete [] encrypted;
1329 return e_weakPw; 1330 return e_weakPw;
1330 } 1331 }
1331 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1332 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1332 break; 1333 break;
1333 } 1334 }
1334 case PWM_CRYPT_AES128: 1335 case PWM_CRYPT_AES128:
1335 /*... fall through */ 1336 /*... fall through */
1336 case PWM_CRYPT_AES192: 1337 case PWM_CRYPT_AES192:
1337 case PWM_CRYPT_AES256: 1338 case PWM_CRYPT_AES256:
1338 case PWM_CRYPT_3DES: 1339 case PWM_CRYPT_3DES:
1339 case PWM_CRYPT_TWOFISH: 1340 case PWM_CRYPT_TWOFISH:
1340 case PWM_CRYPT_TWOFISH128: { 1341 case PWM_CRYPT_TWOFISH128: {
1341 if (!LibGCryptIf::available()) 1342 if (!LibGCryptIf::available())
1342 return e_cryptNotImpl; 1343 return e_cryptNotImpl;
1343 LibGCryptIf gc; 1344 LibGCryptIf gc;
1344 PwMerror err; 1345 PwMerror err;
1345 unsigned char *plain = new unsigned char[d->length() + 1024]; 1346 unsigned char *plain = new unsigned char[d->length() + 1024];
1346 memcpy(plain, d->c_str(), d->length()); 1347 memcpy(plain, d->c_str(), d->length());
1347 err = gc.encrypt(&encrypted, 1348 err = gc.encrypt(&encrypted,
1348 &encSize, 1349 &encSize,
1349 plain, 1350 plain,
1350 d->length(), 1351 d->length(),
1351 reinterpret_cast<const unsigned char *>(pw->latin1()), 1352 reinterpret_cast<const unsigned char *>(pw->latin1()),
1352 pw->length(), 1353 pw->length(),
1353 algo, 1354 algo,
1354 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1355 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1355 ); 1356 );
1356 delete [] plain; 1357 delete [] plain;
1357 if (err != e_success) 1358 if (err != e_success)
1358 return e_cryptNotImpl; 1359 return e_cryptNotImpl;
1359 break; 1360 break;
1360 } 1361 }
1361 default: { 1362 default: {
1362 delete_ifnot_null_array(encrypted); 1363 delete_ifnot_null_array(encrypted);
1363 return e_cryptNotImpl; 1364 return e_cryptNotImpl;
1364 } } 1365 } }
1365 1366
1366 // write encrypted data to file 1367 // write encrypted data to file
1367 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1368 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1368 static_cast<Q_ULONG>(encSize)) 1369 static_cast<Q_ULONG>(encSize))
1369 != static_cast<Q_LONG>(encSize)) { 1370 != static_cast<Q_LONG>(encSize)) {
1370 delete_ifnot_null_array(encrypted); 1371 delete_ifnot_null_array(encrypted);
1371 return e_writeFile; 1372 return e_writeFile;
1372 } 1373 }
1373 delete_ifnot_null_array(encrypted); 1374 delete_ifnot_null_array(encrypted);
1374 return e_success; 1375 return e_success;
1375} 1376}
1376 1377
1377PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1378PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1378 char algo, 1379 char algo,
1379 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase 1380 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
1380 QFile *f) 1381 QFile *f)
1381{ 1382{
1382 PWM_ASSERT(d); 1383 PWM_ASSERT(d);
1383 PWM_ASSERT(pw); 1384 PWM_ASSERT(pw);
1384 PWM_ASSERT(f); 1385 PWM_ASSERT(f);
1385 1386
1386 unsigned int cryptLen = f->size() - pos; 1387 unsigned int cryptLen = f->size() - pos;
1387 byte *encrypted = new byte[cryptLen]; 1388 byte *encrypted = new byte[cryptLen];
1388 byte *decrypted = new byte[cryptLen]; 1389 byte *decrypted = new byte[cryptLen];
1389 1390
1390 f->at(pos); 1391 f->at(pos);
1391#ifndef PWM_EMBEDDED 1392#ifndef PWM_EMBEDDED
1392 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1393 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1393 static_cast<Q_ULONG>(cryptLen)) 1394 static_cast<Q_ULONG>(cryptLen))
1394 != static_cast<Q_LONG>(cryptLen)) { 1395 != static_cast<Q_LONG>(cryptLen)) {
1395 delete [] encrypted; 1396 delete [] encrypted;
1396 delete [] decrypted; 1397 delete [] decrypted;
1397 return e_readFile; 1398 return e_readFile;
1398 } 1399 }
1399#else 1400#else
1400 if (f->readBlock((char *)(encrypted), 1401 if (f->readBlock((char *)(encrypted),
1401 (unsigned long)(cryptLen)) 1402 (unsigned long)(cryptLen))
1402 != (long)(cryptLen)) { 1403 != (long)(cryptLen)) {
1403 delete [] encrypted; 1404 delete [] encrypted;
1404 delete [] decrypted; 1405 delete [] decrypted;
1405 return e_readFile; 1406 return e_readFile;
1406 } 1407 }
1407#endif 1408#endif
1408 switch (algo) { 1409 switch (algo) {
1409 case PWM_CRYPT_BLOWFISH: { 1410 case PWM_CRYPT_BLOWFISH: {
1410 Blowfish bf; 1411 Blowfish bf;
1411 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1412 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1412 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1413 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1413 break; 1414 break;
1414 } 1415 }
1415 case PWM_CRYPT_AES128: 1416 case PWM_CRYPT_AES128:
1416 /*... fall through */ 1417 /*... fall through */
1417 case PWM_CRYPT_AES192: 1418 case PWM_CRYPT_AES192:
1418 case PWM_CRYPT_AES256: 1419 case PWM_CRYPT_AES256:
1419 case PWM_CRYPT_3DES: 1420 case PWM_CRYPT_3DES:
1420 case PWM_CRYPT_TWOFISH: 1421 case PWM_CRYPT_TWOFISH:
1421 case PWM_CRYPT_TWOFISH128: { 1422 case PWM_CRYPT_TWOFISH128: {
1422 if (!LibGCryptIf::available()) 1423 if (!LibGCryptIf::available())
1423 return e_cryptNotImpl; 1424 return e_cryptNotImpl;
1424 LibGCryptIf gc; 1425 LibGCryptIf gc;
1425 PwMerror err; 1426 PwMerror err;
1426 err = gc.decrypt(&decrypted, 1427 err = gc.decrypt(&decrypted,
1427 &cryptLen, 1428 &cryptLen,
1428 encrypted, 1429 encrypted,
1429 cryptLen, 1430 cryptLen,
1430 reinterpret_cast<const unsigned char *>(pw->latin1()), 1431 reinterpret_cast<const unsigned char *>(pw->latin1()),
1431 pw->length(), 1432 pw->length(),
1432 algo, 1433 algo,
1433 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1434 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1434); 1435);
1435 if (err != e_success) { 1436 if (err != e_success) {
1436 delete [] encrypted; 1437 delete [] encrypted;
1437 delete [] decrypted; 1438 delete [] decrypted;
1438 return e_cryptNotImpl; 1439 return e_cryptNotImpl;
1439 } 1440 }
1440 break; 1441 break;
1441 } 1442 }
1442 default: { 1443 default: {
1443 delete [] encrypted; 1444 delete [] encrypted;
1444 delete [] decrypted; 1445 delete [] decrypted;
1445 return e_cryptNotImpl; 1446 return e_cryptNotImpl;
1446 } } 1447 } }
1447 delete [] encrypted; 1448 delete [] encrypted;
1448#ifndef PWM_EMBEDDED 1449#ifndef PWM_EMBEDDED
1449 d->assign(reinterpret_cast<const char *>(decrypted), 1450 d->assign(reinterpret_cast<const char *>(decrypted),
1450 static_cast<string::size_type>(cryptLen)); 1451 static_cast<string::size_type>(cryptLen));
1451#else 1452#else
1452 d->assign((const char *)(decrypted), 1453 d->assign((const char *)(decrypted),
1453 (string::size_type)(cryptLen)); 1454 (string::size_type)(cryptLen));
1454#endif 1455#endif
1455 delete [] decrypted; 1456 delete [] decrypted;
1456 if (algo == PWM_CRYPT_BLOWFISH) { 1457 if (algo == PWM_CRYPT_BLOWFISH) {
1457 if (!Blowfish::unpadNull(d)) { 1458 if (!Blowfish::unpadNull(d)) {
1458 BUG(); 1459 BUG();
1459 return e_readFile; 1460 return e_readFile;
1460 } 1461 }
1461 } 1462 }
1462 return e_success; 1463 return e_success;
1463} 1464}
1464 1465
1465PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1466PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1466 const string *dataStream) 1467 const string *dataStream)
1467{ 1468{
1468 PWM_ASSERT(dataHash); 1469 PWM_ASSERT(dataHash);
1469 PWM_ASSERT(dataStream); 1470 PWM_ASSERT(dataStream);
1470 switch(dataHashType) { 1471 switch(dataHashType) {
1471 case PWM_HASH_SHA1: { 1472 case PWM_HASH_SHA1: {
1472 Sha1 hash; 1473 Sha1 hash;
1473 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); 1474 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
1474 string ret = hash.sha1_read(); 1475 string ret = hash.sha1_read();
1475 if (ret != *dataHash) 1476 if (ret != *dataHash)
1476 return e_fileCorrupt; 1477 return e_fileCorrupt;
1477 break; 1478 break;
1478 } 1479 }
1479 case PWM_HASH_SHA256: 1480 case PWM_HASH_SHA256:
1480 /*... fall through */ 1481 /*... fall through */
1481 case PWM_HASH_SHA384: 1482 case PWM_HASH_SHA384:
1482 case PWM_HASH_SHA512: 1483 case PWM_HASH_SHA512:
1483 case PWM_HASH_MD5: 1484 case PWM_HASH_MD5:
1484 case PWM_HASH_RMD160: 1485 case PWM_HASH_RMD160:
1485 case PWM_HASH_TIGER: { 1486 case PWM_HASH_TIGER: {
1486 if (!LibGCryptIf::available()) 1487 if (!LibGCryptIf::available())
1487 return e_hashNotImpl; 1488 return e_hashNotImpl;
1488 LibGCryptIf gc; 1489 LibGCryptIf gc;
1489 PwMerror err; 1490 PwMerror err;
1490 unsigned char *buf; 1491 unsigned char *buf;
1491 size_t hashLen; 1492 size_t hashLen;
1492 err = gc.hash(&buf, 1493 err = gc.hash(&buf,
1493 &hashLen, 1494 &hashLen,
1494 reinterpret_cast<const unsigned char *>(dataStream->c_str()), 1495 reinterpret_cast<const unsigned char *>(dataStream->c_str()),
1495 dataStream->length(), 1496 dataStream->length(),
1496 dataHashType); 1497 dataHashType);
1497 if (err != e_success) 1498 if (err != e_success)
1498 return e_hashNotImpl; 1499 return e_hashNotImpl;
1499 string calcHash(reinterpret_cast<const char *>(buf), 1500 string calcHash(reinterpret_cast<const char *>(buf),
1500 static_cast<string::size_type>(hashLen)); 1501 static_cast<string::size_type>(hashLen));
1501 delete [] buf; 1502 delete [] buf;
1502 if (calcHash != *dataHash) 1503 if (calcHash != *dataHash)
1503 return e_fileCorrupt; 1504 return e_fileCorrupt;
1504 break; 1505 break;
1505 } 1506 }
1506 default: 1507 default:
1507 return e_hashNotImpl; 1508 return e_hashNotImpl;
1508 } 1509 }
1509 return e_success; 1510 return e_success;
1510} 1511}
1511 1512
1512bool PwMDoc::lockAt(unsigned int category, unsigned int index, 1513bool PwMDoc::lockAt(unsigned int category, unsigned int index,
1513 bool lock) 1514 bool lock)
1514{ 1515{
1515 if (index >= numEntries(category)) { 1516 if (index >= numEntries(category)) {
1516 BUG(); 1517 BUG();
1517 return false; 1518 return false;
1518 } 1519 }
1519 if (lock == dti.dta[category].d[index].lockStat) 1520 if (lock == dti.dta[category].d[index].lockStat)
1520 return true; 1521 return true;
1521 1522
1522 if (!lock && currentPw != "") { 1523 if (!lock && currentPw != "") {
1523 // "unlocking" and "password is already set" 1524 // "unlocking" and "password is already set"
1524 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1525 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1525 // unlocking without pw not allowed 1526 // unlocking without pw not allowed
1526 QString pw; 1527 QString pw;
1527 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1528 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1528 if (pw != "") { 1529 if (pw != "") {
1529 if (pw != currentPw) { 1530 if (pw != currentPw) {
1530 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1531 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1531 return false; 1532 return false;
1532 } else { 1533 } else {
1533 timer()->start(DocTimer::id_mpwTimer); 1534 timer()->start(DocTimer::id_mpwTimer);
1534 } 1535 }
1535 } else { 1536 } else {
1536 return false; 1537 return false;
1537 } 1538 }
1538 } else { 1539 } else {
1539 timer()->start(DocTimer::id_mpwTimer); 1540 timer()->start(DocTimer::id_mpwTimer);
1540 } 1541 }
1541 } 1542 }
1542 1543
1543 dti.dta[category].d[index].lockStat = lock; 1544 dti.dta[category].d[index].lockStat = lock;
1544 dti.dta[category].d[index].rev++; // increment revision counter. 1545 dti.dta[category].d[index].rev++; // increment revision counter.
1545 1546
1546 emitDataChanged(this); 1547 emitDataChanged(this);
1547 if (!lock) 1548 if (!lock)
1548 timer()->start(DocTimer::id_autoLockTimer); 1549 timer()->start(DocTimer::id_autoLockTimer);
1549 1550
1550 return true; 1551 return true;
1551 1552
1552} 1553}
1553 1554
1554bool PwMDoc::lockAt(const QString &category,unsigned int index, 1555bool PwMDoc::lockAt(const QString &category,unsigned int index,
1555 bool lock) 1556 bool lock)
1556{ 1557{
1557 unsigned int cat = 0; 1558 unsigned int cat = 0;
1558 1559
1559 if (!findCategory(category, &cat)) { 1560 if (!findCategory(category, &cat)) {
1560 BUG(); 1561 BUG();
1561 return false; 1562 return false;
1562 } 1563 }
1563 1564
1564 return lockAt(cat, index, lock); 1565 return lockAt(cat, index, lock);
1565} 1566}
1566 1567
1567bool PwMDoc::lockAll(bool lock) 1568bool PwMDoc::lockAll(bool lock)
1568{ 1569{
1569 if (!lock && isDeepLocked()) { 1570 if (!lock && isDeepLocked()) {
1570 PwMerror ret; 1571 PwMerror ret;
1571 ret = deepLock(false); 1572 ret = deepLock(false);
1572 if (ret != e_success) 1573 if (ret != e_success)
1573 return false; 1574 return false;
1574 return true; 1575 return true;
1575 } 1576 }
1576 if (isDocEmpty()) { 1577 if (isDocEmpty()) {
1577 return true; 1578 return true;
1578 } 1579 }
1579 if (!lock && currentPw != "") { 1580 if (!lock && currentPw != "") {
1580 // unlocking and password is already set 1581 // unlocking and password is already set
1581 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1582 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1582 // unlocking without pw not allowed 1583 // unlocking without pw not allowed
1583 QString pw; 1584 QString pw;
1584 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1585 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1585 if (pw != "") { 1586 if (pw != "") {
1586 if (pw != currentPw) { 1587 if (pw != currentPw) {
1587 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1588 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1588 return false; 1589 return false;
1589 } else { 1590 } else {
1590 timer()->start(DocTimer::id_mpwTimer); 1591 timer()->start(DocTimer::id_mpwTimer);
1591 } 1592 }
1592 } else { 1593 } else {
1593 return false; 1594 return false;
1594 } 1595 }
1595 } else { 1596 } else {
1596 timer()->start(DocTimer::id_mpwTimer); 1597 timer()->start(DocTimer::id_mpwTimer);
1597 } 1598 }
1598 } 1599 }
1599 1600
1600 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1601 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1601 catEnd = dti.dta.end(), 1602 catEnd = dti.dta.end(),
1602 catI = catBegin; 1603 catI = catBegin;
1603 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1604 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1604 while (catI != catEnd) { 1605 while (catI != catEnd) {
1605 entrBegin = catI->d.begin(); 1606 entrBegin = catI->d.begin();
1606 entrEnd = catI->d.end(); 1607 entrEnd = catI->d.end();
1607 entrI = entrBegin; 1608 entrI = entrBegin;
1608 while (entrI != entrEnd) { 1609 while (entrI != entrEnd) {
1609 entrI->lockStat = lock; 1610 entrI->lockStat = lock;
1610 entrI->rev++; // increment revision counter. 1611 entrI->rev++; // increment revision counter.
1611 ++entrI; 1612 ++entrI;
1612 } 1613 }
1613 ++catI; 1614 ++catI;
1614 } 1615 }
1615 1616
1616 emitDataChanged(this); 1617 emitDataChanged(this);
1617 if (lock) 1618 if (lock)
1618 timer()->stop(DocTimer::id_autoLockTimer); 1619 timer()->stop(DocTimer::id_autoLockTimer);
1619 else 1620 else
1620 timer()->start(DocTimer::id_autoLockTimer); 1621 timer()->start(DocTimer::id_autoLockTimer);
1621 1622
1622 return true; 1623 return true;
1623} 1624}
1624 1625
1625bool PwMDoc::isLocked(const QString &category, unsigned int index) 1626bool PwMDoc::isLocked(const QString &category, unsigned int index)
1626{ 1627{
1627 unsigned int cat = 0; 1628 unsigned int cat = 0;
1628 1629
1629 if (!findCategory(category, &cat)) { 1630 if (!findCategory(category, &cat)) {
1630 BUG(); 1631 BUG();
1631 return false; 1632 return false;
1632 } 1633 }
1633 1634
1634 return isLocked(cat, index); 1635 return isLocked(cat, index);
1635} 1636}
1636 1637
1637bool PwMDoc::unlockAll_tempoary(bool revert) 1638bool PwMDoc::unlockAll_tempoary(bool revert)
1638{ 1639{
1639 static vector< vector<bool> > *oldLockStates = 0; 1640 static vector< vector<bool> > *oldLockStates = 0;
1640 static bool wasDeepLocked; 1641 static bool wasDeepLocked;
1641 1642
1642 if (revert) {// revert the unlocking 1643 if (revert) {// revert the unlocking
1643 if (oldLockStates) { 1644 if (oldLockStates) {
1644 /* we actually _have_ unlocked something, because 1645 /* we actually _have_ unlocked something, because
1645 * we have allocated space for the oldLockStates. 1646 * we have allocated space for the oldLockStates.
1646 * So, go on and revert them! 1647 * So, go on and revert them!
1647 */ 1648 */
1648 if (wasDeepLocked) { 1649 if (wasDeepLocked) {
1649 PwMerror ret = deepLock(true); 1650 PwMerror ret = deepLock(true);
1650 if (ret == e_success) { 1651 if (ret == e_success) {
1651 /* deep-lock succeed. We are save. 1652 /* deep-lock succeed. We are save.
1652 * (but if it failed, just go on 1653 * (but if it failed, just go on
1653 * lock them normally) 1654 * lock them normally)
1654 */ 1655 */
1655 delete_and_null(oldLockStates); 1656 delete_and_null(oldLockStates);
1656 timer()->start(DocTimer::id_autoLockTimer); 1657 timer()->start(DocTimer::id_autoLockTimer);
1657 printDebug("tempoary unlocking of dta " 1658 printDebug("tempoary unlocking of dta "
1658 "reverted by deep-locking."); 1659 "reverted by deep-locking.");
1659 return true; 1660 return true;
1660 } 1661 }
1661 printDebug("deep-lock failed while reverting! " 1662 printDebug("deep-lock failed while reverting! "
1662 "Falling back to normal-lock."); 1663 "Falling back to normal-lock.");
1663 } 1664 }
1664 if (unlikely(!wasDeepLocked && 1665 if (unlikely(!wasDeepLocked &&
1665 numCategories() != oldLockStates->size())) { 1666 numCategories() != oldLockStates->size())) {
1666 /* DOH! We have modified "dta" while 1667 /* DOH! We have modified "dta" while
1667 * it was unlocked tempoary. DON'T DO THIS! 1668 * it was unlocked tempoary. DON'T DO THIS!
1668 */ 1669 */
1669 BUG(); 1670 BUG();
1670 delete_and_null(oldLockStates); 1671 delete_and_null(oldLockStates);
1671 timer()->start(DocTimer::id_autoLockTimer); 1672 timer()->start(DocTimer::id_autoLockTimer);
1672 return false; 1673 return false;
1673 } 1674 }
1674 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1675 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1675 catEnd = dti.dta.end(), 1676 catEnd = dti.dta.end(),
1676 catI = catBegin; 1677 catI = catBegin;
1677 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1678 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1678 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); 1679 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin();
1679 vector<bool>::iterator oldEntrStatBegin, 1680 vector<bool>::iterator oldEntrStatBegin,
1680 oldEntrStatEnd, 1681 oldEntrStatEnd,
1681 oldEntrStatI; 1682 oldEntrStatI;
1682 while (catI != catEnd) { 1683 while (catI != catEnd) {
1683 entrBegin = catI->d.begin(); 1684 entrBegin = catI->d.begin();
1684 entrEnd = catI->d.end(); 1685 entrEnd = catI->d.end();
1685 entrI = entrBegin; 1686 entrI = entrBegin;
1686 if (likely(!wasDeepLocked)) { 1687 if (likely(!wasDeepLocked)) {
1687 oldEntrStatBegin = oldCatStatI->begin(); 1688 oldEntrStatBegin = oldCatStatI->begin();
1688 oldEntrStatEnd = oldCatStatI->end(); 1689 oldEntrStatEnd = oldCatStatI->end();
1689 oldEntrStatI = oldEntrStatBegin; 1690 oldEntrStatI = oldEntrStatBegin;
1690 if (unlikely(catI->d.size() != oldCatStatI->size())) { 1691 if (unlikely(catI->d.size() != oldCatStatI->size())) {
1691 /* DOH! We have modified "dta" while 1692 /* DOH! We have modified "dta" while
1692 * it was unlocked tempoary. DON'T DO THIS! 1693 * it was unlocked tempoary. DON'T DO THIS!
1693 */ 1694 */
1694 BUG(); 1695 BUG();
1695 delete_and_null(oldLockStates); 1696 delete_and_null(oldLockStates);
1696 timer()->start(DocTimer::id_autoLockTimer); 1697 timer()->start(DocTimer::id_autoLockTimer);
1697 return false; 1698 return false;
1698 } 1699 }
1699 } 1700 }
1700 while (entrI != entrEnd) { 1701 while (entrI != entrEnd) {
1701 if (wasDeepLocked) { 1702 if (wasDeepLocked) {
1702 /* this is an error-fallback if 1703 /* this is an error-fallback if
1703 * deeplock didn't succeed 1704 * deeplock didn't succeed
1704 */ 1705 */
1705 entrI->lockStat = true; 1706 entrI->lockStat = true;
1706 } else { 1707 } else {
1707 entrI->lockStat = *oldEntrStatI; 1708 entrI->lockStat = *oldEntrStatI;
1708 } 1709 }
1709 ++entrI; 1710 ++entrI;
1710 if (likely(!wasDeepLocked)) 1711 if (likely(!wasDeepLocked))
1711 ++oldEntrStatI; 1712 ++oldEntrStatI;
1712 } 1713 }
1713 ++catI; 1714 ++catI;
1714 if (likely(!wasDeepLocked)) 1715 if (likely(!wasDeepLocked))
1715 ++oldCatStatI; 1716 ++oldCatStatI;
1716 } 1717 }
1717 delete_and_null(oldLockStates); 1718 delete_and_null(oldLockStates);
1718 if (unlikely(wasDeepLocked)) { 1719 if (unlikely(wasDeepLocked)) {
1719 /* error fallback... */ 1720 /* error fallback... */
1720 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1721 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1721 emitDataChanged(this); 1722 emitDataChanged(this);
1722 printDebug("WARNING: unlockAll_tempoary(true) " 1723 printDebug("WARNING: unlockAll_tempoary(true) "
1723 "deeplock fallback!"); 1724 "deeplock fallback!");
1724 } 1725 }
1725 printDebug("tempoary unlocking of dta reverted."); 1726 printDebug("tempoary unlocking of dta reverted.");
1726 } else { 1727 } else {
1727 printDebug("unlockAll_tempoary(true): nothing to do."); 1728 printDebug("unlockAll_tempoary(true): nothing to do.");
1728 } 1729 }
1729 timer()->start(DocTimer::id_autoLockTimer); 1730 timer()->start(DocTimer::id_autoLockTimer);
1730 } else {// unlock all data tempoary 1731 } else {// unlock all data tempoary
1731 if (unlikely(oldLockStates != 0)) { 1732 if (unlikely(oldLockStates != 0)) {
1732 /* DOH! We have already unlocked the data tempoarly. 1733 /* DOH! We have already unlocked the data tempoarly.
1733 * No need to do it twice. ;) 1734 * No need to do it twice. ;)
1734 */ 1735 */
1735 BUG(); 1736 BUG();
1736 return false; 1737 return false;
1737 } 1738 }
1738 wasDeepLocked = false; 1739 wasDeepLocked = false;
1739 bool mustUnlock = false; 1740 bool mustUnlock = false;
1740 if (isDeepLocked()) { 1741 if (isDeepLocked()) {
1741 PwMerror ret; 1742 PwMerror ret;
1742 while (1) { 1743 while (1) {
1743 ret = deepLock(false); 1744 ret = deepLock(false);
1744 if (ret == e_success) { 1745 if (ret == e_success) {
1745 break; 1746 break;
1746 } else if (ret == e_wrongPw) { 1747 } else if (ret == e_wrongPw) {
1747 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1748 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1748 } else { 1749 } else {
1749 printDebug("deep-unlocking failed while " 1750 printDebug("deep-unlocking failed while "
1750 "tempoary unlocking!"); 1751 "tempoary unlocking!");
1751 return false; 1752 return false;
1752 } 1753 }
1753 } 1754 }
1754 wasDeepLocked = true; 1755 wasDeepLocked = true;
1755 mustUnlock = true; 1756 mustUnlock = true;
1756 } else { 1757 } else {
1757 // first check if it's needed to unlock some entries 1758 // first check if it's needed to unlock some entries
1758 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1759 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1759 catEnd = dti.dta.end(), 1760 catEnd = dti.dta.end(),
1760 catI = catBegin; 1761 catI = catBegin;
1761 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1762 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1762 while (catI != catEnd) { 1763 while (catI != catEnd) {
1763 entrBegin = catI->d.begin(); 1764 entrBegin = catI->d.begin();
1764 entrEnd = catI->d.end(); 1765 entrEnd = catI->d.end();
1765 entrI = entrBegin; 1766 entrI = entrBegin;
1766 while (entrI != entrEnd) { 1767 while (entrI != entrEnd) {
1767 if (entrI->lockStat == true) { 1768 if (entrI->lockStat == true) {
1768 mustUnlock = true; 1769 mustUnlock = true;
1769 break; 1770 break;
1770 } 1771 }
1771 ++entrI; 1772 ++entrI;
1772 } 1773 }
1773 if (mustUnlock) 1774 if (mustUnlock)
1774 break; 1775 break;
1775 ++catI; 1776 ++catI;
1776 } 1777 }
1777 } 1778 }
1778 if (!mustUnlock) { 1779 if (!mustUnlock) {
1779 // nothing to do. 1780 // nothing to do.
1780 timer()->stop(DocTimer::id_autoLockTimer); 1781 timer()->stop(DocTimer::id_autoLockTimer);
1781 printDebug("unlockAll_tempoary(): nothing to do."); 1782 printDebug("unlockAll_tempoary(): nothing to do.");
1782 return true; 1783 return true;
1783 } else if (!wasDeepLocked) { 1784 } else if (!wasDeepLocked) {
1784 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && 1785 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) &&
1785 currentPw != "") { 1786 currentPw != "") {
1786 /* we can't unlock without mpw, so 1787 /* we can't unlock without mpw, so
1787 * we need to ask for it. 1788 * we need to ask for it.
1788 */ 1789 */
1789 QString pw; 1790 QString pw;
1790 while (1) { 1791 while (1) {
1791 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1792 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1792 if (pw == "") { 1793 if (pw == "") {
1793 return false; 1794 return false;
1794 } else if (pw == currentPw) { 1795 } else if (pw == currentPw) {
1795 break; 1796 break;
1796 } 1797 }
1797 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1798 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1798 } 1799 }
1799 } 1800 }
1800 } 1801 }
1801 timer()->stop(DocTimer::id_autoLockTimer); 1802 timer()->stop(DocTimer::id_autoLockTimer);
1802 oldLockStates = new vector< vector<bool> >; 1803 oldLockStates = new vector< vector<bool> >;
1803 vector<bool> tmp_vec; 1804 vector<bool> tmp_vec;
1804 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1805 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1805 catEnd = dti.dta.end(), 1806 catEnd = dti.dta.end(),
1806 catI = catBegin; 1807 catI = catBegin;
1807 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1808 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1808 while (catI != catEnd) { 1809 while (catI != catEnd) {
1809 entrBegin = catI->d.begin(); 1810 entrBegin = catI->d.begin();
1810 entrEnd = catI->d.end(); 1811 entrEnd = catI->d.end();
1811 entrI = entrBegin; 1812 entrI = entrBegin;
1812 while (entrI != entrEnd) { 1813 while (entrI != entrEnd) {
1813 if (!wasDeepLocked) { 1814 if (!wasDeepLocked) {
1814 tmp_vec.push_back(entrI->lockStat); 1815 tmp_vec.push_back(entrI->lockStat);
1815 } 1816 }
1816 entrI->lockStat = false; 1817 entrI->lockStat = false;
1817 ++entrI; 1818 ++entrI;
1818 } 1819 }
1819 if (!wasDeepLocked) { 1820 if (!wasDeepLocked) {
1820 oldLockStates->push_back(tmp_vec); 1821 oldLockStates->push_back(tmp_vec);
1821 tmp_vec.clear(); 1822 tmp_vec.clear();
1822 } 1823 }
1823 ++catI; 1824 ++catI;
1824 } 1825 }
1825 printDebug("tempoary unlocked dta."); 1826 printDebug("tempoary unlocked dta.");
1826 } 1827 }
1827 1828
1828 return true; 1829 return true;
1829} 1830}
1830 1831
1831PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) 1832PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
1832{ 1833{
1833 PwMerror ret; 1834 PwMerror ret;
1834 /* NOTE: saveDoc() depends on this function to return 1835 /* NOTE: saveDoc() depends on this function to return
1835 * e_success if saveToFile == false 1836 * e_success if saveToFile == false
1836 */ 1837 */
1837 1838
1838 if (lock) { 1839 if (lock) {
1839 if (isDeepLocked()) 1840 if (isDeepLocked())
1840 return e_lock; 1841 return e_lock;
1841 if (saveToFile) { 1842 if (saveToFile) {
1842 if (isDocEmpty()) 1843 if (isDocEmpty())
1843 return e_docIsEmpty; 1844 return e_docIsEmpty;
1844 ret = saveDoc(conf()->confGlobCompression()); 1845 ret = saveDoc(conf()->confGlobCompression());
1845 if (ret == e_filename) { 1846 if (ret == e_filename) {
1846 /* the doc wasn't saved to a file 1847 /* the doc wasn't saved to a file
1847 * by the user, yet. 1848 * by the user, yet.
1848 */ 1849 */
1849 cantDeeplock_notSavedMsgBox(); 1850 cantDeeplock_notSavedMsgBox();
1850 return e_docNotSaved; 1851 return e_docNotSaved;
1851 } else if (ret != e_success) { 1852 } else if (ret != e_success) {
1852 return e_lock; 1853 return e_lock;
1853 } 1854 }
1854 } 1855 }
1855 timer()->stop(DocTimer::id_autoLockTimer); 1856 timer()->stop(DocTimer::id_autoLockTimer);
1856 clearDoc(); 1857 clearDoc();
1857 PwMDataItem d; 1858 PwMDataItem d;
1858 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); 1859 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
1859 d.comment = IS_DEEPLOCKED_MSG.latin1(); 1860 d.comment = IS_DEEPLOCKED_MSG.latin1();
1860 d.listViewPos = 0; 1861 d.listViewPos = 0;
1861 addEntry(DEFAULT_CATEGORY, &d, true); 1862 addEntry(DEFAULT_CATEGORY, &d, true);
1862 lockAt(DEFAULT_CATEGORY, 0, true); 1863 lockAt(DEFAULT_CATEGORY, 0, true);
1863 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 1864 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
1864 setDocStatFlag(DOC_STAT_DEEPLOCKED); 1865 setDocStatFlag(DOC_STAT_DEEPLOCKED);
1865 } else { 1866 } else {
1866 if (!isDeepLocked()) 1867 if (!isDeepLocked())
1867 return e_lock; 1868 return e_lock;
1868 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) 1869 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
1869 ? 0 : 1); 1870 ? 0 : 1);
1870 if (ret == e_wrongPw) { 1871 if (ret == e_wrongPw) {
1871 return e_wrongPw; 1872 return e_wrongPw;
1872 } else if (ret != e_success) { 1873 } else if (ret != e_success) {
1873 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") 1874 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
1874 + tostr(static_cast<int>(ret))); 1875 + tostr(static_cast<int>(ret)));
1875 return e_lock; 1876 return e_lock;
1876 } 1877 }
1877 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1878 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1878 timer()->start(DocTimer::id_autoLockTimer); 1879 timer()->start(DocTimer::id_autoLockTimer);
1879 } 1880 }
1880 1881
1881 emitDataChanged(this); 1882 emitDataChanged(this);
1882 return e_success; 1883 return e_success;
1883} 1884}
1884 1885
1885void PwMDoc::_deepUnlock() 1886void PwMDoc::_deepUnlock()
1886{ 1887{
1887 deepLock(false); 1888 deepLock(false);
1888} 1889}
1889 1890
1890void PwMDoc::clearDoc() 1891void PwMDoc::clearDoc()
1891{ 1892{
1892 dti.clear(); 1893 dti.clear();
1893 PwMCategoryItem d; 1894 PwMCategoryItem d;
1894 //US ENH: to initialize all members with meaningfull data. 1895 //US ENH: to initialize all members with meaningfull data.
1895 d.clear(); 1896 d.clear();
1896 d.name = DEFAULT_CATEGORY.latin1(); 1897 d.name = DEFAULT_CATEGORY.latin1();
1897 dti.dta.push_back(d); 1898 dti.dta.push_back(d);
1898 currentPw = ""; 1899 currentPw = "";
1899 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 1900 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
1900} 1901}
1901 1902
1902void PwMDoc::changeCurrentPw() 1903void PwMDoc::changeCurrentPw()
1903{ 1904{
1904 if (currentPw == "") 1905 if (currentPw == "")
1905 return; // doc hasn't been saved. No mpw available. 1906 return; // doc hasn't been saved. No mpw available.
1906 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 1907 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
1907 QString pw = requestMpwChange(&currentPw, &useChipcard); 1908 QString pw = requestMpwChange(&currentPw, &useChipcard);
1908 if (pw == "") 1909 if (pw == "")
1909 return; 1910 return;
1910 if (useChipcard) 1911 if (useChipcard)
1911 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 1912 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
1912 else 1913 else
1913 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 1914 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
1914 setCurrentPw(pw); 1915 setCurrentPw(pw);
1915} 1916}
1916 1917
1917void PwMDoc::setListViewPos(const QString &category, unsigned int index, 1918void PwMDoc::setListViewPos(const QString &category, unsigned int index,
1918 int pos) 1919 int pos)
1919{ 1920{
1920 unsigned int cat = 0; 1921 unsigned int cat = 0;
1921 1922
1922 if (!findCategory(category, &cat)) { 1923 if (!findCategory(category, &cat)) {
1923 BUG(); 1924 BUG();
1924 return; 1925 return;
1925 } 1926 }
1926 setListViewPos(cat, index, pos); 1927 setListViewPos(cat, index, pos);
1927} 1928}
1928 1929
1929void PwMDoc::setListViewPos(unsigned int category, unsigned int index, 1930void PwMDoc::setListViewPos(unsigned int category, unsigned int index,
1930 int pos) 1931 int pos)
1931{ 1932{
1932 dti.dta[category].d[index].listViewPos = pos; 1933 dti.dta[category].d[index].listViewPos = pos;
1933 1934
1934/* FIXME workaround: don't flag dirty, because this function sometimes 1935/* FIXME workaround: don't flag dirty, because this function sometimes
1935 * get's called when it shouldn't. It's because PwMView assumes 1936 * get's called when it shouldn't. It's because PwMView assumes
1936 * the user resorted the UI on behalf of signal layoutChanged(). 1937 * the user resorted the UI on behalf of signal layoutChanged().
1937 * This is somewhat broken and incorrect, but I've no other 1938 * This is somewhat broken and incorrect, but I've no other
1938 * solution for now. 1939 * solution for now.
1939 */ 1940 */
1940 //setDocStatFlag(DOC_STAT_DISK_DIRTY); 1941 //setDocStatFlag(DOC_STAT_DISK_DIRTY);
1941} 1942}
1942 1943
1943int PwMDoc::getListViewPos(const QString &category, unsigned int index) 1944int PwMDoc::getListViewPos(const QString &category, unsigned int index)
1944{ 1945{
1945 unsigned int cat = 0; 1946 unsigned int cat = 0;
1946 1947
1947 if (!findCategory(category, &cat)) { 1948 if (!findCategory(category, &cat)) {
1948 BUG(); 1949 BUG();
1949 return -1; 1950 return -1;
1950 } 1951 }
1951 1952
1952 return dti.dta[cat].d[index].listViewPos; 1953 return dti.dta[cat].d[index].listViewPos;
1953} 1954}
1954 1955
1955void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, 1956void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
1956 vector<unsigned int> *foundPositions, bool breakAfterFound, 1957 vector<unsigned int> *foundPositions, bool breakAfterFound,
1957 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 1958 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
1958{ 1959{
1959 PWM_ASSERT(foundPositions); 1960 PWM_ASSERT(foundPositions);
1960 PWM_ASSERT(searchIn); 1961 PWM_ASSERT(searchIn);
1961 foundPositions->clear(); 1962 foundPositions->clear();
1962 1963
1963 unsigned int i, entries = numEntries(category); 1964 unsigned int i, entries = numEntries(category);
1964 for (i = 0; i < entries; ++i) { 1965 for (i = 0; i < entries; ++i) {
1965 if (searchIn & SEARCH_IN_DESC) { 1966 if (searchIn & SEARCH_IN_DESC) {
1966 if (!compareString(find.desc, dti.dta[category].d[i].desc, 1967 if (!compareString(find.desc, dti.dta[category].d[i].desc,
1967 caseSensitive, exactWordMatch)) { 1968 caseSensitive, exactWordMatch)) {
1968 continue; 1969 continue;
1969 } 1970 }
1970 } 1971 }
1971 if (searchIn & SEARCH_IN_NAME) { 1972 if (searchIn & SEARCH_IN_NAME) {
1972 if (!compareString(find.name, dti.dta[category].d[i].name, 1973 if (!compareString(find.name, dti.dta[category].d[i].name,
1973 caseSensitive, exactWordMatch)) { 1974 caseSensitive, exactWordMatch)) {
1974 continue; 1975 continue;
1975 } 1976 }
1976 } 1977 }
1977 if (searchIn & SEARCH_IN_PW) { 1978 if (searchIn & SEARCH_IN_PW) {
1978 bool wasLocked = isLocked(category, i); 1979 bool wasLocked = isLocked(category, i);
1979 getDataChangedLock(); 1980 getDataChangedLock();
1980 lockAt(category, i, false); 1981 lockAt(category, i, false);
1981 if (!compareString(find.pw, dti.dta[category].d[i].pw, 1982 if (!compareString(find.pw, dti.dta[category].d[i].pw,
1982 caseSensitive, exactWordMatch)) { 1983 caseSensitive, exactWordMatch)) {
1983 lockAt(category, i, wasLocked); 1984 lockAt(category, i, wasLocked);
1984 putDataChangedLock(); 1985 putDataChangedLock();
1985 continue; 1986 continue;
1986 } 1987 }
1987 lockAt(category, i, wasLocked); 1988 lockAt(category, i, wasLocked);
1988 putDataChangedLock(); 1989 putDataChangedLock();
1989 } 1990 }
1990 if (searchIn & SEARCH_IN_COMMENT) { 1991 if (searchIn & SEARCH_IN_COMMENT) {
1991 if (!compareString(find.comment, dti.dta[category].d[i].comment, 1992 if (!compareString(find.comment, dti.dta[category].d[i].comment,
1992 caseSensitive, exactWordMatch)) { 1993 caseSensitive, exactWordMatch)) {
1993 continue; 1994 continue;
1994 } 1995 }
1995 } 1996 }
1996 if (searchIn & SEARCH_IN_URL) { 1997 if (searchIn & SEARCH_IN_URL) {
1997 if (!compareString(find.url, dti.dta[category].d[i].url, 1998 if (!compareString(find.url, dti.dta[category].d[i].url,
1998 caseSensitive, exactWordMatch)) { 1999 caseSensitive, exactWordMatch)) {
1999 continue; 2000 continue;
2000 } 2001 }
2001 } 2002 }
2002 if (searchIn & SEARCH_IN_LAUNCHER) { 2003 if (searchIn & SEARCH_IN_LAUNCHER) {
2003 if (!compareString(find.launcher, dti.dta[category].d[i].launcher, 2004 if (!compareString(find.launcher, dti.dta[category].d[i].launcher,
2004 caseSensitive, exactWordMatch)) { 2005 caseSensitive, exactWordMatch)) {
2005 continue; 2006 continue;
2006 } 2007 }
2007 } 2008 }
2008 2009
2009 // all selected "searchIn" matched. 2010 // all selected "searchIn" matched.
2010 foundPositions->push_back(i); 2011 foundPositions->push_back(i);
2011 if (breakAfterFound) 2012 if (breakAfterFound)
2012 break; 2013 break;
2013 } 2014 }
2014 2015
2015 if (sortByLvp && foundPositions->size() > 1) { 2016 if (sortByLvp && foundPositions->size() > 1) {
2016 vector< pair<unsigned int /* foundPosition (real doc pos) */, 2017 vector< pair<unsigned int /* foundPosition (real doc pos) */,
2017 unsigned int /* lvp-pos */> > tmp_vec; 2018 unsigned int /* lvp-pos */> > tmp_vec;
2018 2019
2019 unsigned int i, items = foundPositions->size(); 2020 unsigned int i, items = foundPositions->size();
2020 pair<unsigned int, unsigned int> tmp_pair; 2021 pair<unsigned int, unsigned int> tmp_pair;
2021 for (i = 0; i < items; ++i) { 2022 for (i = 0; i < items; ++i) {
2022 tmp_pair.first = (*foundPositions)[i]; 2023 tmp_pair.first = (*foundPositions)[i];
2023 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; 2024 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos;
2024 tmp_vec.push_back(tmp_pair); 2025 tmp_vec.push_back(tmp_pair);
2025 } 2026 }
2026 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); 2027 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater());
2027 foundPositions->clear(); 2028 foundPositions->clear();
2028 for (i = 0; i < items; ++i) { 2029 for (i = 0; i < items; ++i) {
2029 foundPositions->push_back(tmp_vec[i].first); 2030 foundPositions->push_back(tmp_vec[i].first);
2030 } 2031 }
2031 } 2032 }
2032} 2033}
2033 2034
2034void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, 2035void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
2035 vector<unsigned int> *foundPositions, bool breakAfterFound, 2036 vector<unsigned int> *foundPositions, bool breakAfterFound,
2036 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 2037 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
2037{ 2038{
2038 PWM_ASSERT(foundPositions); 2039 PWM_ASSERT(foundPositions);
2039 unsigned int cat = 0; 2040 unsigned int cat = 0;
2040 2041
2041 if (!findCategory(category, &cat)) { 2042 if (!findCategory(category, &cat)) {
2042 foundPositions->clear(); 2043 foundPositions->clear();
2043 return; 2044 return;
2044 } 2045 }
2045 2046
2046 findEntry(cat, find, searchIn, foundPositions, breakAfterFound, 2047 findEntry(cat, find, searchIn, foundPositions, breakAfterFound,
2047 caseSensitive, exactWordMatch, sortByLvp); 2048 caseSensitive, exactWordMatch, sortByLvp);
2048} 2049}
2049 2050
2050bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, 2051bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive,
2051 bool exactWordMatch) 2052 bool exactWordMatch)
2052{ 2053{
2053 QString _s1(s1.c_str()); 2054 QString _s1(s1.c_str());
2054 QString _s2(s2.c_str()); 2055 QString _s2(s2.c_str());
2055 if (!caseSensitive) { 2056 if (!caseSensitive) {
2056 _s1 = _s1.lower(); 2057 _s1 = _s1.lower();
2057 _s2 = _s2.lower(); 2058 _s2 = _s2.lower();
2058 } 2059 }
2059 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) 2060 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1))
2060 return true; 2061 return true;
2061 return false; 2062 return false;
2062} 2063}
2063 2064
2064bool PwMDoc::findCategory(const QString &name, unsigned int *index) 2065bool PwMDoc::findCategory(const QString &name, unsigned int *index)
2065{ 2066{
2066 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2067 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2067 end = dti.dta.end(); 2068 end = dti.dta.end();
2068 while (i != end) { 2069 while (i != end) {
2069 if ((*i).name == name.latin1()) { 2070 if ((*i).name == name.latin1()) {
2070 if (index) { 2071 if (index) {
2071 *index = i - dti.dta.begin(); 2072 *index = i - dti.dta.begin();
2072 } 2073 }
2073 return true; 2074 return true;
2074 } 2075 }
2075 ++i; 2076 ++i;
2076 } 2077 }
2077 return false; 2078 return false;
2078} 2079}
2079 2080
2080bool PwMDoc::renameCategory(const QString &category, const QString &newName) 2081bool PwMDoc::renameCategory(const QString &category, const QString &newName)
2081{ 2082{
2082 unsigned int cat = 0; 2083 unsigned int cat = 0;
2083 2084
2084 if (!findCategory(category, &cat)) 2085 if (!findCategory(category, &cat))
2085 return false; 2086 return false;
2086 2087
2087 return renameCategory(cat, newName); 2088 return renameCategory(cat, newName);
2088} 2089}
2089 2090
2090bool PwMDoc::renameCategory(unsigned int category, const QString &newName, 2091bool PwMDoc::renameCategory(unsigned int category, const QString &newName,
2091 bool dontFlagDirty) 2092 bool dontFlagDirty)
2092{ 2093{
2093 if (category > numCategories() - 1) 2094 if (category > numCategories() - 1)
2094 return false; 2095 return false;
2095 2096
2096 dti.dta[category].name = newName.latin1(); 2097 dti.dta[category].name = newName.latin1();
2097 if (!dontFlagDirty) 2098 if (!dontFlagDirty)
2098 flagDirty(); 2099 flagDirty();
2099 2100
2100 return true; 2101 return true;
2101} 2102}
2102 2103
2103bool PwMDoc::delCategory(const QString &category) 2104bool PwMDoc::delCategory(const QString &category)
2104{ 2105{
2105 unsigned int cat = 0; 2106 unsigned int cat = 0;
2106 2107
2107 if (!findCategory(category, &cat)) 2108 if (!findCategory(category, &cat))
2108 return false; 2109 return false;
2109 2110
2110 return delCategory(cat); 2111 return delCategory(cat);
2111} 2112}
2112 2113
2113bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) 2114bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty)
2114{ 2115{
2115 if (category > numCategories() - 1) 2116 if (category > numCategories() - 1)
2116 return false; 2117 return false;
2117 2118
2118 // We don't delete it, if it is the last existing 2119 // We don't delete it, if it is the last existing
2119 // category! Instead we rename it to "Default". 2120 // category! Instead we rename it to "Default".
2120 if (numCategories() > 1) { 2121 if (numCategories() > 1) {
2121 dti.dta.erase(dti.dta.begin() + category); 2122 dti.dta.erase(dti.dta.begin() + category);
2122 } else { 2123 } else {
2123 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); 2124 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty);
diff --git a/pwmanager/pwmanager/pwmview.cpp b/pwmanager/pwmanager/pwmview.cpp
index 7733028..cd816e5 100644
--- a/pwmanager/pwmanager/pwmview.cpp
+++ b/pwmanager/pwmanager/pwmview.cpp
@@ -1,619 +1,620 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.0.1 of pwmanager 14 * This file is originaly based on version 1.0.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 "pwmview.h" 20#include "pwmview.h"
21#include "pwmexception.h" 21#include "pwmexception.h"
22#include "globalstuff.h" 22#include "globalstuff.h"
23#include "pwm.h" 23#include "pwm.h"
24#include "rencatwnd.h" 24#include "rencatwnd.h"
25#ifndef PWM_EMBEDDED 25#ifndef PWM_EMBEDDED
26#include "configuration.h" 26#include "configuration.h"
27#else 27#else
28#include "pwmprefs.h" 28#include "pwmprefs.h"
29#endif 29#endif
30#include "commentbox.h" 30#include "commentbox.h"
31 31
32#include <kmessagebox.h> 32#include <kmessagebox.h>
33#include <klocale.h> 33#include <klocale.h>
34 34
35#include <qlineedit.h> 35#include <qlineedit.h>
36#include <qpoint.h> 36#include <qpoint.h>
37#include <qapplication.h> 37#include <qapplication.h>
38#include <qlayout.h> 38#include <qlayout.h>
39 39
40//US ENH: wouldn't it be a good idea if we could use this consts everywhere else. 40//US ENH: wouldn't it be a good idea if we could use this consts everywhere else.
41//US ENH: for examle in listviewpwm.cpp 41//US ENH: for examle in listviewpwm.cpp
42//US ENH: Because of that I transfer them into the headerfile. 42//US ENH: Because of that I transfer them into the headerfile.
43/* 43/*
44 #define COLUMN_DESC 0 44 #define COLUMN_DESC 0
45 #define COLUMN_NAME 1 45 #define COLUMN_NAME 1
46 #define COLUMN_PW 2 46 #define COLUMN_PW 2
47 #define COLUMN_URL 3 47 #define COLUMN_URL 3
48 #define COLUMN_LAUNCHER 4 48 #define COLUMN_LAUNCHER 4
49*/ 49*/
50 50
51PwMView::PwMView(PwM *_mainClass, 51PwMView::PwMView(PwM *_mainClass,
52 QWidget *parent, PwMDoc *_doc, 52 QWidget *parent, PwMDoc *_doc,
53 const char *name) 53 const char *name)
54 : PwMViewStyle(parent, name) 54 : PwMViewStyle(parent, name)
55{ 55{
56 PWM_ASSERT(_mainClass); 56 PWM_ASSERT(_mainClass);
57 PWM_ASSERT(parent); 57 PWM_ASSERT(parent);
58 PWM_ASSERT(_doc); 58 PWM_ASSERT(_doc);
59 setView(this); 59 setView(this);
60 doc = _doc; 60 doc = _doc;
61 doc->setListViewPointer(this); 61 doc->setListViewPointer(this);
62 mainClass = _mainClass; 62 mainClass = _mainClass;
63 resize(_mainClass->size()); 63 resize(_mainClass->size());
64 initStyle(conf()->confWndMainViewStyle()); 64 initStyle(conf()->confWndMainViewStyle());
65 initCtxMenu(); 65 initCtxMenu();
66 doc->setCurrentView(this); 66 doc->setCurrentView(this);
67 connect(doc, SIGNAL(dataChanged(PwMDoc *)), this, SLOT(updateView())); 67 connect(doc, SIGNAL(dataChanged(PwMDoc *)), this, SLOT(updateView()));
68} 68}
69 69
70PwMView::~PwMView() 70PwMView::~PwMView()
71{ 71{
72} 72}
73 73
74void PwMView::initCtxMenu() 74void PwMView::initCtxMenu()
75{ 75{
76 ctxMenu = new QPopupMenu(this); 76 ctxMenu = new QPopupMenu(this);
77 ctxMenu->insertItem(i18n("&Add password"), mainClass, SLOT(addPwd_slot())); 77 ctxMenu->insertItem(i18n("&Add password"), mainClass, SLOT(addPwd_slot()));
78 ctxMenu->insertSeparator(); 78 ctxMenu->insertSeparator();
79 ctxMenu->insertItem(i18n("&Edit"), mainClass, SLOT(editPwd_slot())); 79 ctxMenu->insertItem(i18n("&Edit"), mainClass, SLOT(editPwd_slot()));
80 ctxMenu->insertItem(i18n("&Delete"), mainClass, SLOT(deletePwd_slot())); 80 ctxMenu->insertItem(i18n("&Delete"), mainClass, SLOT(deletePwd_slot()));
81 ctxMenu->insertSeparator(); 81 ctxMenu->insertSeparator();
82 ctxMenu->insertItem(i18n("copy password to clipboard"), 82 ctxMenu->insertItem(i18n("copy password to clipboard"),
83 this, SLOT(copyPwToClip())); 83 this, SLOT(copyPwToClip()));
84 ctxMenu->insertItem(i18n("copy username to clipboard"), 84 ctxMenu->insertItem(i18n("copy username to clipboard"),
85 this, SLOT(copyNameToClip())); 85 this, SLOT(copyNameToClip()));
86 ctxMenu->insertItem(i18n("copy description to clipboard"), 86 ctxMenu->insertItem(i18n("copy description to clipboard"),
87 this, SLOT(copyDescToClip())); 87 this, SLOT(copyDescToClip()));
88 ctxMenu->insertItem(i18n("copy url to clipboard"), 88 ctxMenu->insertItem(i18n("copy url to clipboard"),
89 this, SLOT(copyUrlToClip())); 89 this, SLOT(copyUrlToClip()));
90 ctxMenu->insertItem(i18n("copy launcher to clipboard"), 90 ctxMenu->insertItem(i18n("copy launcher to clipboard"),
91 this, SLOT(copyLauncherToClip())); 91 this, SLOT(copyLauncherToClip()));
92 ctxMenu->insertItem(i18n("copy comment to clipboard"), 92 ctxMenu->insertItem(i18n("copy comment to clipboard"),
93 this, SLOT(copyCommentToClip())); 93 this, SLOT(copyCommentToClip()));
94 ctxMenu->insertSeparator(); 94 ctxMenu->insertSeparator();
95 ctxMenu->insertItem(i18n("Execute \"Launcher\""), mainClass, 95 ctxMenu->insertItem(i18n("Execute \"Launcher\""), mainClass,
96 SLOT(execLauncher_slot())); 96 SLOT(execLauncher_slot()));
97 ctxMenu->insertItem(i18n("Go to \"URL\""), mainClass, 97 ctxMenu->insertItem(i18n("Go to \"URL\""), mainClass,
98 SLOT(goToURL_slot())); 98 SLOT(goToURL_slot()));
99} 99}
100 100
101void PwMView::resizeEvent(QResizeEvent *) 101void PwMView::resizeEvent(QResizeEvent *)
102{ 102{
103 resizeView(size()); 103 resizeView(size());
104} 104}
105 105
106void PwMView::refreshCommentTextEdit(QListViewItem *curItem) 106void PwMView::refreshCommentTextEdit(QListViewItem *curItem)
107{ 107{
108 PWM_ASSERT(commentBox); 108 PWM_ASSERT(commentBox);
109 if (!curItem) 109 if (!curItem)
110 return; 110 return;
111 string comment; 111 string comment;
112 PwMerror ret; 112 PwMerror ret;
113 ret = document()->getCommentByLvp(getCurrentCategory(), 113 ret = document()->getCommentByLvp(getCurrentCategory(),
114 lv->childCount() - lv->itemIndex(curItem) - 1, 114 lv->childCount() - lv->itemIndex(curItem) - 1,
115 &comment); 115 &comment);
116 if (ret == e_binEntry) { 116 if (ret == e_binEntry) {
117 commentBox->setContent(i18n("This is a binary entry.\n" 117 commentBox->setContent(i18n("This is a binary entry.\n"
118 "It is not a normal password-entry, as it contains " 118 "It is not a normal password-entry, as it contains "
119 "binary data, which PwManager can't display here.")); 119 "binary data, which PwManager can't display here."));
120 } else if (ret == e_normalEntry) { 120 } else if (ret == e_normalEntry) {
121 commentBox->setContent(comment.c_str()); 121 commentBox->setContent(comment.c_str());
122 } else { 122 } else {
123 BUG(); 123 BUG();
124 return; 124 return;
125 } 125 }
126 lv->ensureItemVisible(curItem); 126 lv->ensureItemVisible(curItem);
127} 127}
128 128
129void PwMView::keyReleaseEvent(QKeyEvent * /*e*/) 129void PwMView::keyReleaseEvent(QKeyEvent * /*e*/)
130{ 130{
131 refreshCommentTextEdit(lv->currentItem()); 131 refreshCommentTextEdit(lv->currentItem());
132} 132}
133 133
134bool PwMView::getCurEntryIndex(unsigned int *index) 134bool PwMView::getCurEntryIndex(unsigned int *index)
135{ 135{
136 QListViewItem *current = lv->currentItem(); 136 QListViewItem *current = lv->currentItem();
137 if (!current) 137 if (!current)
138 return false; 138 return false;
139 return getDocEntryIndex(index, current); 139 return getDocEntryIndex(index, current);
140} 140}
141 141
142bool PwMView::getDocEntryIndex(unsigned int *index, 142bool PwMView::getDocEntryIndex(unsigned int *index,
143 const QListViewItem *item) 143 const QListViewItem *item)
144{ 144{
145 vector<unsigned int> foundPositions; 145 vector<unsigned int> foundPositions;
146 PwMDataItem curItem; 146 PwMDataItem curItem;
147 curItem.desc = item->text(COLUMN_DESC).latin1(); 147 curItem.desc = item->text(COLUMN_DESC).latin1();
148 curItem.name = item->text(COLUMN_NAME).latin1(); 148 curItem.name = item->text(COLUMN_NAME).latin1();
149 document()->getCommentByLvp(getCurrentCategory(), 149 document()->getCommentByLvp(getCurrentCategory(),
150 lv->childCount() - lv->itemIndex(item) - 1, 150 lv->childCount() - lv->itemIndex(item) - 1,
151 &curItem.comment); 151 &curItem.comment);
152 curItem.url = item->text(COLUMN_URL).latin1(); 152 curItem.url = item->text(COLUMN_URL).latin1();
153 curItem.launcher = item->text(COLUMN_LAUNCHER).latin1(); 153 curItem.launcher = item->text(COLUMN_LAUNCHER).latin1();
154 document()->findEntry(getCurrentCategory(), curItem, SEARCH_IN_DESC | 154 document()->findEntry(getCurrentCategory(), curItem, SEARCH_IN_DESC |
155 SEARCH_IN_NAME | SEARCH_IN_COMMENT | SEARCH_IN_URL | 155 SEARCH_IN_NAME | SEARCH_IN_COMMENT | SEARCH_IN_URL |
156 SEARCH_IN_LAUNCHER, 156 SEARCH_IN_LAUNCHER,
157 &foundPositions, true); 157 &foundPositions, true);
158 if (foundPositions.size()) { 158 if (foundPositions.size()) {
159 *index = foundPositions[0]; 159 *index = foundPositions[0];
160 return true; 160 return true;
161 } 161 }
162 162
163 return false; 163 return false;
164} 164}
165 165
166void PwMView::handleToggle(QListViewItem *item) 166void PwMView::handleToggle(QListViewItem *item)
167{ 167{
168 PWM_ASSERT(doc); 168 PWM_ASSERT(doc);
169 if (!item) 169 if (!item)
170 return; 170 return;
171 QCheckListItem *clItem = (QCheckListItem *)item; 171 QCheckListItem *clItem = (QCheckListItem *)item;
172 QString curCat(getCurrentCategory()); 172 QString curCat(getCurrentCategory());
173 173
174 // find document position of this entry. 174 // find document position of this entry.
175 unsigned int curEntryDocIndex; 175 unsigned int curEntryDocIndex;
176 if (!getDocEntryIndex(&curEntryDocIndex, item)) 176 if (!getDocEntryIndex(&curEntryDocIndex, item))
177 return; 177 return;
178 178
179 // hack to refresh the comment, if only one item is present 179 // hack to refresh the comment, if only one item is present
180 if (lv->childCount() == 1) 180 if (lv->childCount() == 1)
181 refreshCommentTextEdit(lv->currentItem()); 181 refreshCommentTextEdit(lv->currentItem());
182 182
183 if (doc->isLocked(curCat, curEntryDocIndex) != clItem->isOn()) 183 if (doc->isLocked(curCat, curEntryDocIndex) != clItem->isOn())
184 return; // this is just a click somewhere on the entry 184 return; // this is just a click somewhere on the entry
185 if (doc->isDeepLocked()) { 185 if (doc->isDeepLocked()) {
186 PwMerror ret; 186 PwMerror ret;
187 ret = doc->deepLock(false); 187 ret = doc->deepLock(false);
188 if (ret != e_success) 188 if (ret != e_success)
189 clItem->setOn(false); 189 clItem->setOn(false);
190 return; 190 return;
191 } 191 }
192 doc->lockAt(curCat, curEntryDocIndex, !clItem->isOn()); 192 doc->lockAt(curCat, curEntryDocIndex, !clItem->isOn());
193} 193}
194 194
195void PwMView::handleRightClick(QListViewItem *item, const QPoint &point, int) 195void PwMView::handleRightClick(QListViewItem *item, const QPoint &point, int)
196{ 196{
197 if (!item) 197 if (!item)
198 return; 198 return;
199 ctxMenu->move(point); 199 ctxMenu->move(point);
200 /* don't use ctxMenu->exec() here, as it generates race conditions 200 /* don't use ctxMenu->exec() here, as it generates race conditions
201 * with the card interface code. Believe it or not. :) 201 * with the card interface code. Believe it or not. :)
202 */ 202 */
203 ctxMenu->show(); 203 ctxMenu->show();
204} 204}
205 205
206void PwMView::updateCategories() 206void PwMView::updateCategories()
207{ 207{
208 qDebug("PwMView::updateCategories() ");
208 QString oldSel(getCurrentCategory()); 209 QString oldSel(getCurrentCategory());
209 delAllCategories(); 210 delAllCategories();
210 QStringList catList; 211 QStringList catList;
211 document()->getCategoryList(&catList); 212 document()->getCategoryList(&catList);
212 catList.sort(); 213 catList.sort();
213#ifndef PWM_EMBEDDED 214#ifndef PWM_EMBEDDED
214 QStringList::iterator i = catList.begin(), 215 QStringList::iterator i = catList.begin(),
215 end = catList.end(); 216 end = catList.end();
216#else 217#else
217 QStringList::Iterator i = catList.begin(), 218 QStringList::Iterator i = catList.begin(),
218 end = catList.end(); 219 end = catList.end();
219#endif 220#endif
220 while (i != end) { 221 while (i != end) {
221 addCategory(*i); 222 addCategory(*i);
222 ++i; 223 ++i;
223 } 224 }
224 selectCategory(oldSel); 225 selectCategory(oldSel);
225} 226}
226 227
227void PwMView::shiftToView() 228void PwMView::shiftToView()
228{ 229{
229 int cX = lv->contentsX(); 230 int cX = lv->contentsX();
230 int cY = lv->contentsY(); 231 int cY = lv->contentsY();
231 commentBox->clear(); 232 commentBox->clear();
232 233
233 unsigned int catDocIndex; 234 unsigned int catDocIndex;
234 if (unlikely( 235 if (unlikely(
235 !(document()->findCategory(getCurrentCategory(), 236 !(document()->findCategory(getCurrentCategory(),
236 &catDocIndex)))) { 237 &catDocIndex)))) {
237 BUG(); 238 BUG();
238 } 239 }
239 240
240 // ensure all listViewPos are set 241 // ensure all listViewPos are set
241 doc->ensureLvp(); 242 doc->ensureLvp();
242 243
243 // clear all tmp-data vectors 244 // clear all tmp-data vectors
244 unsigned int i, entries = doc->numEntries(catDocIndex); 245 unsigned int i, entries = doc->numEntries(catDocIndex);
245 if (entries) { 246 if (entries) {
246 mainClass->setVirgin(false); 247 mainClass->setVirgin(false);
247 } 248 }
248 vector<PwMDataItem> tmpSorted; 249 vector<PwMDataItem> tmpSorted;
249 PwMDataItem currItem; 250 PwMDataItem currItem;
250 currItem.clear(); 251 currItem.clear();
251 tmpSorted.insert(tmpSorted.begin(), entries, currItem); 252 tmpSorted.insert(tmpSorted.begin(), entries, currItem);
252 253
253 // Sort items and store them in tempoary tmpSorted. 254 // Sort items and store them in tempoary tmpSorted.
254 for (i = 0; i < entries; ++i) { 255 for (i = 0; i < entries; ++i) {
255 doc->getEntry(catDocIndex, i, &currItem); 256 doc->getEntry(catDocIndex, i, &currItem);
256 //qDebug("PwMView::shiftToView: %s, %i", currItem.desc.c_str(), currItem.listViewPos); 257 //qDebug("PwMView::shiftToView: %s, %i", currItem.desc.c_str(), currItem.listViewPos);
257 tmpSorted[currItem.listViewPos] = currItem; 258 tmpSorted[currItem.listViewPos] = currItem;
258 } 259 }
259 260
260 // shift tempoary data to ListView. 261 // shift tempoary data to ListView.
261 tmpDisableSort(); 262 tmpDisableSort();
262 lv->clear(); 263 lv->clear();
263 264
264 //US ENH: adjust the headers of the table according the category texts 265 //US ENH: adjust the headers of the table according the category texts
265 { 266 {
266 PwMCategoryItem* catItem = doc->getCategoryEntry(catDocIndex); 267 PwMCategoryItem* catItem = doc->getCategoryEntry(catDocIndex);
267 // qDebug("PwMView::ShiftToView CAT: %i, %s", catDocIndex, catItem->name.c_str()); 268 // qDebug("PwMView::ShiftToView CAT: %i, %s", catDocIndex, catItem->name.c_str());
268 lv->setColumnText(COLUMN_DESC, catItem->desc_text.c_str()); 269 lv->setColumnText(COLUMN_DESC, catItem->desc_text.c_str());
269 lv->setColumnText(COLUMN_NAME, catItem->name_text.c_str()); 270 lv->setColumnText(COLUMN_NAME, catItem->name_text.c_str());
270 lv->setColumnText(COLUMN_PW, catItem->pw_text.c_str()); 271 lv->setColumnText(COLUMN_PW, catItem->pw_text.c_str());
271 } 272 }
272 273
273 QCheckListItem *newItem; 274 QCheckListItem *newItem;
274 vector<PwMDataItem>::iterator it = tmpSorted.begin(), 275 vector<PwMDataItem>::iterator it = tmpSorted.begin(),
275 end = tmpSorted.end(); 276 end = tmpSorted.end();
276 while (it != end) { 277 while (it != end) {
277 newItem = new ListViewItemPwM(lv); 278 newItem = new ListViewItemPwM(lv);
278 newItem->setText(COLUMN_DESC, (*it).desc.c_str()); 279 newItem->setText(COLUMN_DESC, (*it).desc.c_str());
279 if ((*it).binary) { 280 if ((*it).binary) {
280 newItem->setText(COLUMN_NAME, ""); 281 newItem->setText(COLUMN_NAME, "");
281 newItem->setText(COLUMN_PW, i18n("<BINARY ENTRY>")); 282 newItem->setText(COLUMN_PW, i18n("<BINARY ENTRY>"));
282 newItem->setText(COLUMN_URL, ""); 283 newItem->setText(COLUMN_URL, "");
283 newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); 284 newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str());
284 } else { 285 } else {
285 newItem->setText(COLUMN_NAME, (*it).name.c_str()); 286 newItem->setText(COLUMN_NAME, (*it).name.c_str());
286 if ((*it).lockStat) { 287 if ((*it).lockStat) {
287 newItem->setText(COLUMN_PW, QString((*it).pw.c_str()) 288 newItem->setText(COLUMN_PW, QString((*it).pw.c_str())
288 + " " 289 + " "
289 + i18n("To unlock click the icon on the left.")); 290 + i18n("To unlock click the icon on the left."));
290 } else { 291 } else {
291 newItem->setText(COLUMN_PW, (*it).pw.c_str()); 292 newItem->setText(COLUMN_PW, (*it).pw.c_str());
292 } 293 }
293 newItem->setText(COLUMN_URL, (*it).url.c_str()); 294 newItem->setText(COLUMN_URL, (*it).url.c_str());
294 newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); 295 newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str());
295 } 296 }
296 newItem->setOn(!((*it).lockStat)); 297 newItem->setOn(!((*it).lockStat));
297 lv->insertItem(newItem); 298 lv->insertItem(newItem);
298 ++it; 299 ++it;
299 } 300 }
300 tmpReEnableSort(); 301 tmpReEnableSort();
301 302
302 if (cY || cX) 303 if (cY || cX)
303 lv->setContentsPos(cX, cY); 304 lv->setContentsPos(cX, cY);
304} 305}
305 306
306void PwMView::reorgLp() 307void PwMView::reorgLp()
307{ 308{
308 if (!lv->childCount()) 309 if (!lv->childCount())
309 return; 310 return;
310 PWM_ASSERT(doc); 311 PWM_ASSERT(doc);
311 PWM_ASSERT(!doc->isDocEmpty()); 312 PWM_ASSERT(!doc->isDocEmpty());
312 QListViewItem *currItem; 313 QListViewItem *currItem;
313 vector<unsigned int> foundPos; 314 vector<unsigned int> foundPos;
314 /* This searchIn _should_ be: 315 /* This searchIn _should_ be:
315 *const unsigned int searchIn = SEARCH_IN_DESC; 316 *const unsigned int searchIn = SEARCH_IN_DESC;
316 * But we want backward compatibility (see comment in PwMDoc::addEntry()). 317 * But we want backward compatibility (see comment in PwMDoc::addEntry()).
317 * So we need to search again, if we don't find the entry. (see below) 318 * So we need to search again, if we don't find the entry. (see below)
318 */ 319 */
319 const unsigned int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 320 const unsigned int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
320 SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 321 SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
321 QString curCat(getCurrentCategory()); 322 QString curCat(getCurrentCategory());
322 PwMDataItem findThis; 323 PwMDataItem findThis;
323 unsigned int i, cnt = lv->childCount(); 324 unsigned int i, cnt = lv->childCount();
324 for (i = 0; i < cnt; ++i) { 325 for (i = 0; i < cnt; ++i) {
325 currItem = lv->itemAtIndex(i); 326 currItem = lv->itemAtIndex(i);
326 findThis.desc = currItem->text(COLUMN_DESC).latin1(); 327 findThis.desc = currItem->text(COLUMN_DESC).latin1();
327 findThis.name = currItem->text(COLUMN_NAME).latin1(); 328 findThis.name = currItem->text(COLUMN_NAME).latin1();
328 findThis.url = currItem->text(COLUMN_URL).latin1(); 329 findThis.url = currItem->text(COLUMN_URL).latin1();
329 findThis.launcher = currItem->text(COLUMN_LAUNCHER).latin1(); 330 findThis.launcher = currItem->text(COLUMN_LAUNCHER).latin1();
330 doc->findEntry(curCat, findThis, searchIn, 331 doc->findEntry(curCat, findThis, searchIn,
331 &foundPos, true); 332 &foundPos, true);
332 if (!foundPos.size()) { 333 if (!foundPos.size()) {
333 /* Did not find the entry. We seem to have a binary 334 /* Did not find the entry. We seem to have a binary
334 * entry here (pray for it!). So search again with 335 * entry here (pray for it!). So search again with
335 * the "correct" searchIn flags. 336 * the "correct" searchIn flags.
336 */ 337 */
337 const unsigned int searchIn2 = SEARCH_IN_DESC; 338 const unsigned int searchIn2 = SEARCH_IN_DESC;
338 doc->findEntry(curCat, findThis, searchIn2, 339 doc->findEntry(curCat, findThis, searchIn2,
339 &foundPos, true); 340 &foundPos, true);
340 if (unlikely(!foundPos.size())) { 341 if (unlikely(!foundPos.size())) {
341 BUG(); 342 BUG();
342 continue; 343 continue;
343 } 344 }
344 /* We assert that it's a binary entry, now. 345 /* We assert that it's a binary entry, now.
345 * No chance to efficiently verify it here. 346 * No chance to efficiently verify it here.
346 */ 347 */
347 } 348 }
348 doc->setListViewPos(curCat, foundPos[0], cnt - i - 1); 349 doc->setListViewPos(curCat, foundPos[0], cnt - i - 1);
349 } 350 }
350} 351}
351 352
352void PwMView::selAt(int index) 353void PwMView::selAt(int index)
353{ 354{
354 QListViewItem *item = lv->itemAtIndex(index); 355 QListViewItem *item = lv->itemAtIndex(index);
355 if (!item) 356 if (!item)
356 return; 357 return;
357 lv->setCurrentItem(item); 358 lv->setCurrentItem(item);
358 lv->ensureItemVisible(item); 359 lv->ensureItemVisible(item);
359} 360}
360 361
361void PwMView::renCatButton_slot() 362void PwMView::renCatButton_slot()
362{ 363{
363 if (doc->isDeepLocked()) 364 if (doc->isDeepLocked())
364 return; 365 return;
365 RenCatWnd wnd(this); 366 RenCatWnd wnd(this);
366 if (wnd.exec() == 1) { 367 if (wnd.exec() == 1) {
367 QString newName(wnd.getNewName()); 368 QString newName(wnd.getNewName());
368 if (newName == "") 369 if (newName == "")
369 return; 370 return;
370 document()->renameCategory(getCurrentCategory(), 371 document()->renameCategory(getCurrentCategory(),
371 newName); 372 newName);
372 } 373 }
373} 374}
374 375
375void PwMView::delCatButton_slot() 376void PwMView::delCatButton_slot()
376{ 377{
377 if (doc->isDeepLocked()) 378 if (doc->isDeepLocked())
378 return; 379 return;
379 if (numCategories() <= 1) { 380 if (numCategories() <= 1) {
380 mainClass->showStatMsg(i18n("Can't remove the last category.")); 381 mainClass->showStatMsg(i18n("Can't remove the last category."));
381 return; 382 return;
382 } 383 }
383 if (KMessageBox::questionYesNo(this, 384 if (KMessageBox::questionYesNo(this,
384 i18n("Do you really want to\n" 385 i18n("Do you really want to\n"
385 "delete the selected\n" 386 "delete the selected\n"
386 "category? All password-\n" 387 "category? All password-\n"
387 "entries will be lost in\n" 388 "entries will be lost in\n"
388 "this category!\n"), 389 "this category!\n"),
389 i18n("Delete category?")) 390 i18n("Delete category?"))
390 == KMessageBox::No) { 391 == KMessageBox::No) {
391 return; 392 return;
392 } 393 }
393 document()->delCategory(getCurrentCategory()); 394 document()->delCategory(getCurrentCategory());
394} 395}
395 396
396void PwMView::copyPwToClip() 397void PwMView::copyPwToClip()
397{ 398{
398 if (doc->isDeepLocked()) 399 if (doc->isDeepLocked())
399 return; 400 return;
400 unsigned int curIndex = 0; 401 unsigned int curIndex = 0;
401 if (!getCurEntryIndex(&curIndex)) 402 if (!getCurEntryIndex(&curIndex))
402 return; 403 return;
403 PwMDataItem d; 404 PwMDataItem d;
404 document()->getDataChangedLock(); 405 document()->getDataChangedLock();
405 document()->getEntry(getCurrentCategory(), curIndex, &d, true); 406 document()->getEntry(getCurrentCategory(), curIndex, &d, true);
406 document()->putDataChangedLock(); 407 document()->putDataChangedLock();
407 PwM::copyToClipboard(d.pw.c_str()); 408 PwM::copyToClipboard(d.pw.c_str());
408} 409}
409 410
410void PwMView::copyNameToClip() 411void PwMView::copyNameToClip()
411{ 412{
412 if (doc->isDeepLocked()) 413 if (doc->isDeepLocked())
413 return; 414 return;
414 unsigned int curIndex = 0; 415 unsigned int curIndex = 0;
415 if (!getCurEntryIndex(&curIndex)) 416 if (!getCurEntryIndex(&curIndex))
416 return; 417 return;
417 PwMDataItem d; 418 PwMDataItem d;
418 document()->getEntry(getCurrentCategory(), curIndex, &d); 419 document()->getEntry(getCurrentCategory(), curIndex, &d);
419 PwM::copyToClipboard(d.name.c_str()); 420 PwM::copyToClipboard(d.name.c_str());
420} 421}
421 422
422void PwMView::copyDescToClip() 423void PwMView::copyDescToClip()
423{ 424{
424 if (doc->isDeepLocked()) 425 if (doc->isDeepLocked())
425 return; 426 return;
426 unsigned int curIndex = 0; 427 unsigned int curIndex = 0;
427 if (!getCurEntryIndex(&curIndex)) 428 if (!getCurEntryIndex(&curIndex))
428 return; 429 return;
429 PwMDataItem d; 430 PwMDataItem d;
430 document()->getEntry(getCurrentCategory(), curIndex, &d); 431 document()->getEntry(getCurrentCategory(), curIndex, &d);
431 PwM::copyToClipboard(d.desc.c_str()); 432 PwM::copyToClipboard(d.desc.c_str());
432} 433}
433 434
434void PwMView::copyUrlToClip() 435void PwMView::copyUrlToClip()
435{ 436{
436 if (doc->isDeepLocked()) 437 if (doc->isDeepLocked())
437 return; 438 return;
438 unsigned int curIndex = 0; 439 unsigned int curIndex = 0;
439 if (!getCurEntryIndex(&curIndex)) 440 if (!getCurEntryIndex(&curIndex))
440 return; 441 return;
441 PwMDataItem d; 442 PwMDataItem d;
442 document()->getEntry(getCurrentCategory(), curIndex, &d); 443 document()->getEntry(getCurrentCategory(), curIndex, &d);
443 PwM::copyToClipboard(d.url.c_str()); 444 PwM::copyToClipboard(d.url.c_str());
444} 445}
445 446
446void PwMView::copyLauncherToClip() 447void PwMView::copyLauncherToClip()
447{ 448{
448 if (doc->isDeepLocked()) 449 if (doc->isDeepLocked())
449 return; 450 return;
450 unsigned int curIndex = 0; 451 unsigned int curIndex = 0;
451 if (!getCurEntryIndex(&curIndex)) 452 if (!getCurEntryIndex(&curIndex))
452 return; 453 return;
453 PwMDataItem d; 454 PwMDataItem d;
454 document()->getEntry(getCurrentCategory(), curIndex, &d); 455 document()->getEntry(getCurrentCategory(), curIndex, &d);
455 PwM::copyToClipboard(d.launcher.c_str()); 456 PwM::copyToClipboard(d.launcher.c_str());
456} 457}
457 458
458void PwMView::copyCommentToClip() 459void PwMView::copyCommentToClip()
459{ 460{
460 if (doc->isDeepLocked()) 461 if (doc->isDeepLocked())
461 return; 462 return;
462 unsigned int curIndex = 0; 463 unsigned int curIndex = 0;
463 if (!getCurEntryIndex(&curIndex)) 464 if (!getCurEntryIndex(&curIndex))
464 return; 465 return;
465 PwMDataItem d; 466 PwMDataItem d;
466 document()->getEntry(getCurrentCategory(), curIndex, &d); 467 document()->getEntry(getCurrentCategory(), curIndex, &d);
467 PwM::copyToClipboard(d.comment.c_str()); 468 PwM::copyToClipboard(d.comment.c_str());
468} 469}
469 470
470/************************************************************************ 471/************************************************************************
471 * 472 *
472 * 473 *
473 * 474 *
474 ************************************************************************/ 475 ************************************************************************/
475 476
476 477
477PwMDataItemView::PwMDataItemView( QWidget *parent, const char *name ) 478PwMDataItemView::PwMDataItemView( QWidget *parent, const char *name )
478 : QTextBrowser( parent, name ) 479 : QTextBrowser( parent, name )
479 480
480 481
481{ 482{
482//US setWrapPolicy( QTextEdit::AtWordBoundary ); 483//US setWrapPolicy( QTextEdit::AtWordBoundary );
483 setLinkUnderline( false ); 484 setLinkUnderline( false );
484 // setVScrollBarMode( QScrollView::AlwaysOff ); 485 // setVScrollBarMode( QScrollView::AlwaysOff );
485 //setHScrollBarMode( QScrollView::AlwaysOff ); 486 //setHScrollBarMode( QScrollView::AlwaysOff );
486 487
487//US QStyleSheet *sheet = styleSheet(); 488//US QStyleSheet *sheet = styleSheet();
488//US QStyleSheetItem *link = sheet->item( "a" ); 489//US QStyleSheetItem *link = sheet->item( "a" );
489//US link->setColor( KGlobalSettings::linkColor() ); 490//US link->setColor( KGlobalSettings::linkColor() );
490 491
491} 492}
492 493
493void PwMDataItemView::setPwMDataItem( const PwMDataItem& a ) 494void PwMDataItemView::setPwMDataItem( const PwMDataItem& a )
494 495
495{ 496{
496 mItem = a; 497 mItem = a;
497 // clear view 498 // clear view
498 setText( QString::null ); 499 setText( QString::null );
499 500
500 501
501 QString dynamicPart; 502 QString dynamicPart;
502 QString format = "<tr><td align=\"right\"><b>%1</b></td>" 503 QString format = "<tr><td align=\"right\"><b>%1</b></td>"
503 "<td align=\"left\">%2</td></tr>"; 504 "<td align=\"left\">%2</td></tr>";
504 505
505 dynamicPart += format 506 dynamicPart += format
506 .arg( i18n("LastUpdate") ) 507 .arg( i18n("LastUpdate") )
507 .arg( mItem.meta.update.toString().latin1() ); 508 .arg( mItem.meta.update.toString().latin1() );
508 509
509 dynamicPart += format 510 dynamicPart += format
510 .arg( i18n("Description") ) 511 .arg( i18n("Description") )
511 .arg( mItem.desc.c_str() ); 512 .arg( mItem.desc.c_str() );
512 513
513 dynamicPart += format 514 dynamicPart += format
514 .arg( i18n("Name") ) 515 .arg( i18n("Name") )
515 .arg( mItem.name.c_str() ); 516 .arg( mItem.name.c_str() );
516 517
517 dynamicPart += format 518 dynamicPart += format
518 .arg( i18n("Password") ) 519 .arg( i18n("Password") )
519 .arg( mItem.pw.c_str() ); 520 .arg( mItem.pw.c_str() );
520 521
521 QString comment(mItem.pw.c_str()); 522 QString comment(mItem.pw.c_str());
522 dynamicPart += format 523 dynamicPart += format
523 .arg( i18n("Comment") ) 524 .arg( i18n("Comment") )
524 .arg( comment.replace( QRegExp("\n"), "<br>" ) ); 525 .arg( comment.replace( QRegExp("\n"), "<br>" ) );
525 526
526 dynamicPart += format 527 dynamicPart += format
527 .arg( i18n("URL") ) 528 .arg( i18n("URL") )
528 .arg( mItem.url.c_str() ); 529 .arg( mItem.url.c_str() );
529 530
530 dynamicPart += format 531 dynamicPart += format
531 .arg( i18n("Launcher") ) 532 .arg( i18n("Launcher") )
532 .arg( mItem.launcher.c_str() ); 533 .arg( mItem.launcher.c_str() );
533 534
534 QString mText = "<table><td colspan=\"2\">&nbsp;</td>"; 535 QString mText = "<table><td colspan=\"2\">&nbsp;</td>";
535 536
536 mText += dynamicPart; 537 mText += dynamicPart;
537 mText += "</table>"; 538 mText += "</table>";
538 539
539 // at last display it... 540 // at last display it...
540 setText( mText ); 541 setText( mText );
541 542
542} 543}
543 544
544PwMDataItem PwMDataItemView::pwmdataitem() const 545PwMDataItem PwMDataItemView::pwmdataitem() const
545{ 546{
546 return mItem; 547 return mItem;
547} 548}
548 549
549/************************************************************************ 550/************************************************************************
550 * 551 *
551 * 552 *
552 * 553 *
553 ************************************************************************/ 554 ************************************************************************/
554 555
555 556
556PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool takeloc, QWidget *parent, const char *name ) 557PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool takeloc, QWidget *parent, const char *name )
557 : KDialogBase(parent, name, true , 558 : KDialogBase(parent, name, true ,
558 i18n("Conflict! Please choose Entry!"),Ok|User1|Close,Close, false) 559 i18n("Conflict! Please choose Entry!"),Ok|User1|Close,Close, false)
559{ 560{
560 findButton( Close )->setText( i18n("Cancel Sync")); 561 findButton( Close )->setText( i18n("Cancel Sync"));
561 findButton( Ok )->setText( i18n("Remote")); 562 findButton( Ok )->setText( i18n("Remote"));
562 findButton( User1 )->setText( i18n("Local")); 563 findButton( User1 )->setText( i18n("Local"));
563 QWidget* topframe = new QWidget( this ); 564 QWidget* topframe = new QWidget( this );
564 setMainWidget( topframe ); 565 setMainWidget( topframe );
565 QBoxLayout* bl; 566 QBoxLayout* bl;
566 if ( QApplication::desktop()->width() < 640 ) { 567 if ( QApplication::desktop()->width() < 640 ) {
567 bl = new QVBoxLayout( topframe ); 568 bl = new QVBoxLayout( topframe );
568 } else { 569 } else {
569 bl = new QHBoxLayout( topframe ); 570 bl = new QHBoxLayout( topframe );
570 } 571 }
571 QVBox* subframe = new QVBox( topframe ); 572 QVBox* subframe = new QVBox( topframe );
572 bl->addWidget(subframe ); 573 bl->addWidget(subframe );
573 QLabel* lab = new QLabel( i18n("Local Entry"), subframe ); 574 QLabel* lab = new QLabel( i18n("Local Entry"), subframe );
574 if ( takeloc ) 575 if ( takeloc )
575 lab->setBackgroundColor(Qt::green.light() ); 576 lab->setBackgroundColor(Qt::green.light() );
576 PwMDataItemView * av = new PwMDataItemView( subframe ); 577 PwMDataItemView * av = new PwMDataItemView( subframe );
577 av->setPwMDataItem( loc ); 578 av->setPwMDataItem( loc );
578 subframe = new QVBox( topframe ); 579 subframe = new QVBox( topframe );
579 bl->addWidget(subframe ); 580 bl->addWidget(subframe );
580 lab = new QLabel( i18n("Remote Entry"), subframe ); 581 lab = new QLabel( i18n("Remote Entry"), subframe );
581 if ( !takeloc ) 582 if ( !takeloc )
582 lab->setBackgroundColor(Qt::green.light() ); 583 lab->setBackgroundColor(Qt::green.light() );
583 av = new PwMDataItemView( subframe ); 584 av = new PwMDataItemView( subframe );
584 av->setPwMDataItem( rem ); 585 av->setPwMDataItem( rem );
585 QObject::connect(findButton( Ok ),SIGNAL(clicked()),this, SLOT(slot_remote())); 586 QObject::connect(findButton( Ok ),SIGNAL(clicked()),this, SLOT(slot_remote()));
586 QObject::connect(this,SIGNAL(user1Clicked()),this, SLOT(slot_local())); 587 QObject::connect(this,SIGNAL(user1Clicked()),this, SLOT(slot_local()));
587#ifndef DESKTOP_VERSION 588#ifndef DESKTOP_VERSION
588 showMaximized(); 589 showMaximized();
589#else 590#else
590 resize ( 640, 400 ); 591 resize ( 640, 400 );
591#endif 592#endif
592} 593}
593 594
594int PwMDataItemChooser::executeD( bool local ) 595int PwMDataItemChooser::executeD( bool local )
595{ 596{
596 mSyncResult = 3; 597 mSyncResult = 3;
597 if ( local ) 598 if ( local )
598 findButton( User1 )->setFocus(); 599 findButton( User1 )->setFocus();
599 else 600 else
600 findButton( Ok )->setFocus(); 601 findButton( Ok )->setFocus();
601 exec(); 602 exec();
602 return mSyncResult; 603 return mSyncResult;
603} 604}
604void PwMDataItemChooser::slot_remote() 605void PwMDataItemChooser::slot_remote()
605{ 606{
606 mSyncResult = 2; 607 mSyncResult = 2;
607 accept(); 608 accept();
608} 609}
609void PwMDataItemChooser::slot_local() 610void PwMDataItemChooser::slot_local()
610{ 611{
611 mSyncResult = 1; 612 mSyncResult = 1;
612 accept(); 613 accept();
613} 614}
614 615
615 616
616 617
617#ifndef PWM_EMBEDDED 618#ifndef PWM_EMBEDDED
618#include "pwmview.moc" 619#include "pwmview.moc"
619#endif 620#endif