summaryrefslogtreecommitdiffabout
path: root/pwmanager
authorzautrix <zautrix>2004-12-04 22:43:14 (UTC)
committer zautrix <zautrix>2004-12-04 22:43:14 (UTC)
commite4e75984b6cb581d87d436cb6c5140eb57dbdc51 (patch) (unidiff)
treebd3a1ddf191fd16d24dad9910c0b806cee23000e /pwmanager
parentac994c86c3037dbe2273e62c46115b942b09fdcc (diff)
downloadkdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.zip
kdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.tar.gz
kdepimpi-e4e75984b6cb581d87d436cb6c5140eb57dbdc51.tar.bz2
set pwmpi update timer from 10 sec to 5 min
Diffstat (limited to 'pwmanager') (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,1099 +1,1100 @@
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.
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