summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--kabc/plugins/file/resourcefile.cpp49
-rw-r--r--kabc/plugins/file/resourcefile.h1
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp45
3 files changed, 93 insertions, 2 deletions
diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp
index 2bd9e71..c89939d 100644
--- a/kabc/plugins/file/resourcefile.cpp
+++ b/kabc/plugins/file/resourcefile.cpp
@@ -1,433 +1,478 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h> 29#include <sys/stat.h>
30#ifndef _WIN32_ 30#ifndef _WIN32_
31#include <unistd.h> 31#include <unistd.h>
32#endif 32#endif
33 33
34#include <qfile.h> 34#include <qfile.h>
35#include <qfileinfo.h> 35#include <qfileinfo.h>
36#include <qregexp.h> 36#include <qregexp.h>
37#include <qtimer.h> 37#include <qtimer.h>
38 38
39#include <kapplication.h> 39#include <kapplication.h>
40#include <kconfig.h> 40#include <kconfig.h>
41#include <kdebug.h> 41#include <kdebug.h>
42#include <klocale.h> 42#include <klocale.h>
43//US #include <ksavefile.h> 43//US #include <ksavefile.h>
44#include <kstandarddirs.h> 44#include <kstandarddirs.h>
45#include <kmessagebox.h> 45#include <kmessagebox.h>
46#include <kglobalsettings.h>
46 47
47#include "formatfactory.h" 48#include "formatfactory.h"
48 49
49#include "resource.h" 50#include "resource.h"
50#include "resourcefileconfig.h" 51#include "resourcefileconfig.h"
51#include "stdaddressbook.h" 52#include "stdaddressbook.h"
52#define NO_DIRWATCH 53#define NO_DIRWATCH
53#include "resourcefile.h" 54#include "resourcefile.h"
54 55
55//#define ALLOW_LOCKING 56//#define ALLOW_LOCKING
56 57
57 58
58using namespace KABC; 59using namespace KABC;
59 60
60extern "C" 61extern "C"
61#ifdef _WIN32_ 62#ifdef _WIN32_
62__declspec(dllexport) 63__declspec(dllexport)
63#else 64#else
64{ 65{
65#endif 66#endif
66 67
67//US void *init_kabc_file() 68//US void *init_kabc_file()
68 void *init_microkabc_file() 69 void *init_microkabc_file()
69 { 70 {
70 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>(); 71 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>();
71 } 72 }
72#ifndef _WIN32_ 73#ifndef _WIN32_
73} 74}
74#endif 75#endif
75 76
76ResourceFile::ResourceFile( const KConfig *config ) 77ResourceFile::ResourceFile( const KConfig *config )
77 : Resource( config ) , mFormat( 0 ) 78 : Resource( config ) , mFormat( 0 )
78{ 79{
79 QString fileName, formatName, default_fileName; 80 QString fileName, formatName, default_fileName;
80 81
81 default_fileName = StdAddressBook::fileName(); 82 default_fileName = StdAddressBook::fileName();
82 83 mLastBackupDate = -1;
83 KConfig *cfg = (KConfig *)config; 84 KConfig *cfg = (KConfig *)config;
84 if ( cfg ) { 85 if ( cfg ) {
85 fileName = cfg->readEntry( "FileName", default_fileName ); 86 fileName = cfg->readEntry( "FileName", default_fileName );
86 formatName = cfg->readEntry( "FileFormat", "vcard" ); 87 formatName = cfg->readEntry( "FileFormat", "vcard" );
87 mFamily = cfg->readEntry( "ResourceName", "std" ); 88 mFamily = cfg->readEntry( "ResourceName", "std" );
89 mLastBackupDate = cfg->readNumEntry( "LastBackupDate", 0 );
88 } else { 90 } else {
89 fileName = default_fileName; 91 fileName = default_fileName;
90 formatName = "vcard"; 92 formatName = "vcard";
91 } 93 }
92 94
93 init( fileName, formatName ); 95 init( fileName, formatName );
94} 96}
95 97
96ResourceFile::ResourceFile( const QString &fileName , 98ResourceFile::ResourceFile( const QString &fileName ,
97 const QString &formatName ) 99 const QString &formatName )
98 : Resource( 0 ) 100 : Resource( 0 )
99{ 101{
100// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1()); 102// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1());
101 103
102 104
103 105 mLastBackupDate = -1;
104 init( fileName, formatName ); 106 init( fileName, formatName );
105} 107}
106 108
107void ResourceFile::init( const QString &fileName, const QString &formatName ) 109void ResourceFile::init( const QString &fileName, const QString &formatName )
108{ 110{
109 mFormatName = formatName; 111 mFormatName = formatName;
110 112
111 FormatFactory *factory = FormatFactory::self(); 113 FormatFactory *factory = FormatFactory::self();
112 mFormat = factory->format( mFormatName ); 114 mFormat = factory->format( mFormatName );
113 115
114 if ( !mFormat ) { 116 if ( !mFormat ) {
115 mFormatName = "vcard"; 117 mFormatName = "vcard";
116 mFormat = factory->format( mFormatName ); 118 mFormat = factory->format( mFormatName );
117 } 119 }
118 120
119#ifndef NO_DIRWATCH 121#ifndef NO_DIRWATCH
120 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); 122 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
121 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); 123 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
122 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); 124 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
123#endif 125#endif
124 126
125 QString localKdeDir; 127 QString localKdeDir;
126 localKdeDir = readEnvPath("LOCALMICROKDEHOME"); 128 localKdeDir = readEnvPath("LOCALMICROKDEHOME");
127 if ( ! localKdeDir.isEmpty() ) { 129 if ( ! localKdeDir.isEmpty() ) {
128 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() ); 130 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() );
129 QFileInfo fi ( fileName ); 131 QFileInfo fi ( fileName );
130 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName (); 132 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName ();
131 QFileInfo fi2 ( localname ); 133 QFileInfo fi2 ( localname );
132 if ( ! fi2.exists() || mFamily == "sync_res" ) { 134 if ( ! fi2.exists() || mFamily == "sync_res" ) {
133 if ( fi.exists() && mFamily == "sync_res") { 135 if ( fi.exists() && mFamily == "sync_res") {
134 qDebug("LOCAL mode SYNC mode using absolute file path "); 136 qDebug("LOCAL mode SYNC mode using absolute file path ");
135 setFileName( fileName ); 137 setFileName( fileName );
136 return; 138 return;
137 } else { 139 } else {
138 KMessageBox::error(0,i18n("Addressbook resource file not found:\n '%1'.\nIn LOCAL mode only resource files in\n'%2'\nare supported.\n(i.e. in the dir ./apps/kabc/ relative to the kapi(.exe) binary.)\n\nIf you are starting KA/Pi for the very first time\nyou will get this error message as well.\nIt will create the missing file automatically for you.").arg(localname).arg(localKdeDir+"/apps/kabc/") ); 140 KMessageBox::error(0,i18n("Addressbook resource file not found:\n '%1'.\nIn LOCAL mode only resource files in\n'%2'\nare supported.\n(i.e. in the dir ./apps/kabc/ relative to the kapi(.exe) binary.)\n\nIf you are starting KA/Pi for the very first time\nyou will get this error message as well.\nIt will create the missing file automatically for you.").arg(localname).arg(localKdeDir+"/apps/kabc/") );
139 setFileName( localname ); 141 setFileName( localname );
140 return; 142 return;
141 } 143 }
142 144
143 } else { 145 } else {
144 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() ); 146 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() );
145 setFileName( localname ); 147 setFileName( localname );
146 return; 148 return;
147 } 149 }
148 150
149 } 151 }
150 setFileName( fileName ); 152 setFileName( fileName );
151} 153}
152 154
153ResourceFile::~ResourceFile() 155ResourceFile::~ResourceFile()
154{ 156{
155 delete mFormat; 157 delete mFormat;
156 mFormat = 0; 158 mFormat = 0;
157} 159}
158 160
159void ResourceFile::writeConfig( KConfig *config ) 161void ResourceFile::writeConfig( KConfig *config )
160{ 162{
161 163
162 config->setGroup( "Resource_" + identifier() ); 164 config->setGroup( "Resource_" + identifier() );
163 Resource::writeConfig( config ); 165 Resource::writeConfig( config );
164 166
165 config->writeEntry( "FileName", fileName() ); 167 config->writeEntry( "FileName", fileName() );
166 config->writeEntry( "FileFormat", mFormatName ); 168 config->writeEntry( "FileFormat", mFormatName );
167 169
168// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1()); 170// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1());
169 171
170} 172}
171 173
172Ticket *ResourceFile::requestSaveTicket() 174Ticket *ResourceFile::requestSaveTicket()
173{ 175{
174 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl; 176 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
175 177
176 if ( !addressBook() ) return 0; 178 if ( !addressBook() ) return 0;
177 179
178#ifdef ALLOW_LOCKING 180#ifdef ALLOW_LOCKING
179 if ( !lock( mFileName ) ) { 181 if ( !lock( mFileName ) ) {
180 qDebug("unablt to lock file "); 182 qDebug("unablt to lock file ");
181 return 0; 183 return 0;
182 } 184 }
183#endif 185#endif
184 return createTicket( this ); 186 return createTicket( this );
185} 187}
186 188
187 189
188bool ResourceFile::doOpen() 190bool ResourceFile::doOpen()
189{ 191{
190 QFile file( fileName() ); 192 QFile file( fileName() );
191 qDebug("ResourceFile::openfile %s ", fileName().latin1()); 193 qDebug("ResourceFile::openfile %s ", fileName().latin1());
192 194
193 if ( !file.exists() ) { 195 if ( !file.exists() ) {
194 // try to create the file 196 // try to create the file
195 bool ok = file.open( IO_WriteOnly ); 197 bool ok = file.open( IO_WriteOnly );
196 if ( ok ) 198 if ( ok )
197 file.close(); 199 file.close();
198 200
199 return ok; 201 return ok;
200 } else { 202 } else {
201 if ( !file.open( IO_ReadWrite ) ) 203 if ( !file.open( IO_ReadWrite ) )
202 return false; 204 return false;
203 205
204 if ( file.size() < 10 ) { 206 if ( file.size() < 10 ) {
205 file.close(); 207 file.close();
206 return true; 208 return true;
207 } 209 }
208 210
209 bool ok = mFormat->checkFormat( &file ); 211 bool ok = mFormat->checkFormat( &file );
210 file.close(); 212 file.close();
211 213
212 return ok; 214 return ok;
213 } 215 }
214} 216}
215 217
216void ResourceFile::doClose() 218void ResourceFile::doClose()
217{ 219{
218} 220}
219 221
220bool ResourceFile::load() 222bool ResourceFile::load()
221{ 223{
222 224
223 QFile file( fileName() ); 225 QFile file( fileName() );
224 if ( !file.open( IO_ReadOnly ) ) { 226 if ( !file.open( IO_ReadOnly ) ) {
225 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) ); 227 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) );
226 return false; 228 return false;
227 } 229 }
228 230
229// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1()); 231// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1());
230 232
231 return mFormat->loadAll( addressBook(), this, &file ); 233 return mFormat->loadAll( addressBook(), this, &file );
232} 234}
233 235
234bool ResourceFile::save( Ticket *ticket ) 236bool ResourceFile::save( Ticket *ticket )
235{ 237{
236// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1()); 238// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1());
237 239
238 240
239 // create backup file 241 // create backup file
240 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() ); 242 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() );
241 243
242/*US we use a simpler method to create a backupfile 244/*US we use a simpler method to create a backupfile
243 245
244 (void) KSaveFile::backupFile( mFileName, QString::null 246 (void) KSaveFile::backupFile( mFileName, QString::null
245 ,extension ); 247 ,extension );
246 248
247 KSaveFile saveFile( mFileName ); 249 KSaveFile saveFile( mFileName );
248 bool ok = false; 250 bool ok = false;
249 if ( saveFile.status() == 0 && saveFile.file() ) 251 if ( saveFile.status() == 0 && saveFile.file() )
250 { 252 {
251 mFormat->saveAll( addressBook(), this, saveFile.file() ); 253 mFormat->saveAll( addressBook(), this, saveFile.file() );
252 ok = saveFile.close(); 254 ok = saveFile.close();
253 } 255 }
254*/ 256*/
255 257
256//US ToDo: write backupfile 258//US ToDo: write backupfile
257#ifndef NO_DIRWATCH 259#ifndef NO_DIRWATCH
258 mDirWatch.stopScan(); 260 mDirWatch.stopScan();
259#endif 261#endif
262 if ( mLastBackupDate >= 0 && mFamily != "sync_res") {
263 KConfig conf (locateLocal("config","microkdeglobalrc"));
264 conf.setGroup( "BackupSettings" );
265 bool b_enabled = conf.readBoolEntry( "BackupEnabled" );
266 if ( b_enabled ) {
267 int num = conf.readNumEntry( "BackupNumbers" );
268 int d_count = conf.readNumEntry( "BackupDayCount" );
269 bool stdDir = conf.readBoolEntry( "BackupUseDefaultDir" );
270 QString bupDir = conf.readEntry( "BackupDatadir" );
271 QDate reference ( 2000,1,1 );
272 int daysTo = reference.daysTo ( QDate::currentDate() );
273 bool saveDate = false;
274 if ( daysTo - d_count >= mLastBackupDate ) {
275 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
276 if ( stdDir )
277 bupDir = KGlobalSettings::backupDataDir();
278 int retval = KApplication::createBackup( fileName(), bupDir, num );
279 if ( retval == 0 ) {
280 qDebug("KO: Backup cancelled. Will try again tomorrow ");
281 // retval == 0 : backup skipped for today, try again tomorrow
282 mLastBackupDate = daysTo - d_count+1;
283 saveDate = true;
284 } else if ( retval == 1 ){
285 qDebug("KO: Backup created.");
286 // backup ok
287 mLastBackupDate = daysTo;
288 saveDate = true;
289 } else if ( retval == 2 ){
290 qDebug("KO: Backup globally cancelled.");
291 // backup globally cancelled
292 b_enabled = false;
293 }
294 if ( !b_enabled ) {
295 conf.writeEntry( "mBackupEnabled", false );
296 }
297 if ( saveDate ) {
298 KConfig config ( locateLocal("config","kabcrc") );
299 config.setGroup( "Resource_" + identifier() );
300 config.writeEntry( "LastBackupDate", mLastBackupDate );
301 }
302 }
303 }
304 }
260 QFile info; 305 QFile info;
261 info.setName( fileName() ); 306 info.setName( fileName() );
262 bool ok = info.open( IO_WriteOnly ); 307 bool ok = info.open( IO_WriteOnly );
263 if ( ok ) { 308 if ( ok ) {
264 mFormat->saveAll( addressBook(), this, &info ); 309 mFormat->saveAll( addressBook(), this, &info );
265 310
266 info.close(); 311 info.close();
267 ok = true; 312 ok = true;
268 } 313 }
269 else { 314 else {
270 315
271 } 316 }
272 317
273 if ( !ok ) 318 if ( !ok )
274 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) ); 319 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) );
275#ifndef NO_DIRWATCH 320#ifndef NO_DIRWATCH
276 mDirWatch.startScan(); 321 mDirWatch.startScan();
277#endif 322#endif
278 delete ticket; 323 delete ticket;
279#ifdef ALLOW_LOCKING 324#ifdef ALLOW_LOCKING
280 unlock( mFileName ); 325 unlock( mFileName );
281#endif 326#endif
282 327
283 return ok; 328 return ok;
284} 329}
285 330
286bool ResourceFile::lock( const QString &fileName ) 331bool ResourceFile::lock( const QString &fileName )
287{ 332{
288#ifdef ALLOW_LOCKING 333#ifdef ALLOW_LOCKING
289 334
290 335
291 QString fn = fileName; 336 QString fn = fileName;
292 337
293//US change the implementation how the lockfilename is getting created 338//US change the implementation how the lockfilename is getting created
294//US fn.replace( QRegExp("/"), "_" ); 339//US fn.replace( QRegExp("/"), "_" );
295//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 340//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
296 341
297 KURL url(fn); 342 KURL url(fn);
298 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 343 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
299 344
300 345
301 346
302 if (QFile::exists( lockName )) return false; 347 if (QFile::exists( lockName )) return false;
303 348
304 QString lockUniqueName; 349 QString lockUniqueName;
305 lockUniqueName = fn + KApplication::randomString( 8 ); 350 lockUniqueName = fn + KApplication::randomString( 8 );
306 351
307 url = lockUniqueName; 352 url = lockUniqueName;
308//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); 353//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
309 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); 354 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() );
310 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; 355 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
311 356
312 // Create unique file 357 // Create unique file
313 QFile file( mLockUniqueName ); 358 QFile file( mLockUniqueName );
314 file.open( IO_WriteOnly ); 359 file.open( IO_WriteOnly );
315 file.close(); 360 file.close();
316 361
317 // Create lock file 362 // Create lock file
318 int result = 0; 363 int result = 0;
319#ifndef _WIN32_ 364#ifndef _WIN32_
320 result = ::link( QFile::encodeName( mLockUniqueName ), 365 result = ::link( QFile::encodeName( mLockUniqueName ),
321 QFile::encodeName( lockName ) ); 366 QFile::encodeName( lockName ) );
322#endif 367#endif
323 if ( result == 0 ) { 368 if ( result == 0 ) {
324 addressBook()->emitAddressBookLocked(); 369 addressBook()->emitAddressBookLocked();
325 return true; 370 return true;
326 } 371 }
327 372
328 // TODO: check stat 373 // TODO: check stat
329 374
330 return false; 375 return false;
331#else 376#else
332 return true; 377 return true;
333#endif 378#endif
334} 379}
335 380
336void ResourceFile::unlock( const QString &fileName ) 381void ResourceFile::unlock( const QString &fileName )
337{ 382{
338#ifdef ALLOW_LOCKING 383#ifdef ALLOW_LOCKING
339 QString fn = fileName; 384 QString fn = fileName;
340//US change the implementation how the lockfilename is getting created 385//US change the implementation how the lockfilename is getting created
341//US fn.replace( QRegExp( "/" ), "_" ); 386//US fn.replace( QRegExp( "/" ), "_" );
342//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 387//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
343//US QString lockName = fn + ".lock"; 388//US QString lockName = fn + ".lock";
344 KURL url(fn); 389 KURL url(fn);
345 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 390 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
346 391
347 QFile::remove( lockName ); 392 QFile::remove( lockName );
348 QFile::remove( mLockUniqueName ); 393 QFile::remove( mLockUniqueName );
349 addressBook()->emitAddressBookUnlocked(); 394 addressBook()->emitAddressBookUnlocked();
350#else 395#else
351 return; 396 return;
352#endif 397#endif
353} 398}
354 399
355void ResourceFile::setFileName( const QString &fileName ) 400void ResourceFile::setFileName( const QString &fileName )
356{ 401{
357#ifndef NO_DIRWATCH 402#ifndef NO_DIRWATCH
358 mDirWatch.stopScan(); 403 mDirWatch.stopScan();
359 mDirWatch.removeFile( mFileName ); 404 mDirWatch.removeFile( mFileName );
360 mFileName = fileName; 405 mFileName = fileName;
361 406
362 407
363 mDirWatch.addFile( mFileName ); 408 mDirWatch.addFile( mFileName );
364 mDirWatch.startScan(); 409 mDirWatch.startScan();
365#else 410#else
366 mFileName2 = fileName; 411 mFileName2 = fileName;
367#endif 412#endif
368 413
369//US simulate KDirWatch event 414//US simulate KDirWatch event
370//US fileChanged(); 415//US fileChanged();
371} 416}
372 417
373QString ResourceFile::fileName() const 418QString ResourceFile::fileName() const
374{ 419{
375 return mFileName2; 420 return mFileName2;
376} 421}
377 422
378void ResourceFile::setFormat( const QString &format ) 423void ResourceFile::setFormat( const QString &format )
379{ 424{
380 mFormatName = format; 425 mFormatName = format;
381 delete mFormat; 426 delete mFormat;
382 427
383 FormatFactory *factory = FormatFactory::self(); 428 FormatFactory *factory = FormatFactory::self();
384 mFormat = factory->format( mFormatName ); 429 mFormat = factory->format( mFormatName );
385/*US 430/*US
386//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1()); 431//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1());
387 if (mFormatName == "vcard") { 432 if (mFormatName == "vcard") {
388 mFormat = new VCardFormatPlugin2(); 433 mFormat = new VCardFormatPlugin2();
389// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 434// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
390 } 435 }
391 else if (mFormatName == "binary") { 436 else if (mFormatName == "binary") {
392 mFormat = new BinaryFormat(); 437 mFormat = new BinaryFormat();
393// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 438// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
394 } 439 }
395 else 440 else
396 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1()); 441 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1());
397*/ 442*/
398 443
399} 444}
400 445
401QString ResourceFile::format() const 446QString ResourceFile::format() const
402{ 447{
403 return mFormatName; 448 return mFormatName;
404} 449}
405 450
406void ResourceFile::fileChanged() 451void ResourceFile::fileChanged()
407{ 452{
408 // There is a small theoretical chance that KDirWatch calls us before 453 // There is a small theoretical chance that KDirWatch calls us before
409 // we are fully constructed 454 // we are fully constructed
410 if (!addressBook()) 455 if (!addressBook())
411 return; 456 return;
412 457
413 458
414 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) ); 459 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) );
415 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) { 460 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) {
416 load(); 461 load();
417 addressBook()->emitAddressBookChanged(); 462 addressBook()->emitAddressBookChanged();
418 } 463 }
419} 464}
420 465
421void ResourceFile::removeAddressee( const Addressee &addr ) 466void ResourceFile::removeAddressee( const Addressee &addr )
422{ 467{
423 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) ); 468 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
424 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) ); 469 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
425 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) ); 470 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) );
426} 471}
427 472
428void ResourceFile::cleanUp() 473void ResourceFile::cleanUp()
429{ 474{
430 unlock( fileName() ); 475 unlock( fileName() );
431} 476}
432 477
433//US #include "resourcefile.moc" 478//US #include "resourcefile.moc"
diff --git a/kabc/plugins/file/resourcefile.h b/kabc/plugins/file/resourcefile.h
index 3e9edfc..61da154 100644
--- a/kabc/plugins/file/resourcefile.h
+++ b/kabc/plugins/file/resourcefile.h
@@ -1,164 +1,165 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28 28
29#ifndef KABC_RESOURCEFILE_H 29#ifndef KABC_RESOURCEFILE_H
30#define KABC_RESOURCEFILE_H 30#define KABC_RESOURCEFILE_H
31 31
32#include <kconfig.h> 32#include <kconfig.h>
33#include <kdirwatch.h> 33#include <kdirwatch.h>
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36 36
37#include <resource.h> 37#include <resource.h>
38 38
39class QTimer; 39class QTimer;
40class FormatPlugin; 40class FormatPlugin;
41 41
42namespace KABC { 42namespace KABC {
43 43
44//US class FormatPlugin; 44//US class FormatPlugin;
45class ResourceConfigWidget; 45class ResourceConfigWidget;
46 46
47/** 47/**
48 @internal 48 @internal
49*/ 49*/
50class ResourceFile : public Resource 50class ResourceFile : public Resource
51{ 51{
52 Q_OBJECT 52 Q_OBJECT
53 53
54public: 54public:
55 55
56 /** 56 /**
57 Constructor. 57 Constructor.
58 58
59 @param cfg The config object where custom resource settings are stored. 59 @param cfg The config object where custom resource settings are stored.
60 */ 60 */
61 ResourceFile( const KConfig *cfg ); 61 ResourceFile( const KConfig *cfg );
62 62
63 /** 63 /**
64 Construct file resource on file @arg fileName using format @arg formatName. 64 Construct file resource on file @arg fileName using format @arg formatName.
65 */ 65 */
66 ResourceFile( const QString &fileName , const QString &formatName = "vcard" ); 66 ResourceFile( const QString &fileName , const QString &formatName = "vcard" );
67 67
68 /** 68 /**
69 * Destructor. 69 * Destructor.
70 */ 70 */
71 ~ResourceFile(); 71 ~ResourceFile();
72 72
73 /** 73 /**
74 Writes the config back. 74 Writes the config back.
75 */ 75 */
76 virtual void writeConfig( KConfig *cfg ); 76 virtual void writeConfig( KConfig *cfg );
77 77
78 /** 78 /**
79 * Tries to open the file and checks for the proper format. 79 * Tries to open the file and checks for the proper format.
80 * This method should be called before @ref load(). 80 * This method should be called before @ref load().
81 */ 81 */
82 virtual bool doOpen(); 82 virtual bool doOpen();
83 83
84 /** 84 /**
85 * Closes the file again. 85 * Closes the file again.
86 */ 86 */
87 virtual void doClose(); 87 virtual void doClose();
88 88
89 /** 89 /**
90 * Requests a save ticket, that is used by @ref save() 90 * Requests a save ticket, that is used by @ref save()
91 */ 91 */
92 virtual Ticket *requestSaveTicket(); 92 virtual Ticket *requestSaveTicket();
93 93
94 /** 94 /**
95 * Loads all addressees from file to the address book. 95 * Loads all addressees from file to the address book.
96 * Returns true if all addressees could be loaded otherwise false. 96 * Returns true if all addressees could be loaded otherwise false.
97 */ 97 */
98 virtual bool load(); 98 virtual bool load();
99 99
100 /** 100 /**
101 * Saves all addresses from address book to file. 101 * Saves all addresses from address book to file.
102 * Returns true if all addressees could be saved otherwise false. 102 * Returns true if all addressees could be saved otherwise false.
103 * 103 *
104 * @param ticket The ticket returned by @ref requestSaveTicket() 104 * @param ticket The ticket returned by @ref requestSaveTicket()
105 */ 105 */
106 virtual bool save( Ticket *ticket ); 106 virtual bool save( Ticket *ticket );
107 107
108 /** 108 /**
109 * Set name of file to be used for saving. 109 * Set name of file to be used for saving.
110 */ 110 */
111 void setFileName( const QString & ); 111 void setFileName( const QString & );
112 112
113 /** 113 /**
114 * Return name of file used for loading and saving the address book. 114 * Return name of file used for loading and saving the address book.
115 */ 115 */
116 QString fileName() const; 116 QString fileName() const;
117 117
118 /** 118 /**
119 Sets a new format by name. 119 Sets a new format by name.
120 */ 120 */
121 void setFormat( const QString &name ); 121 void setFormat( const QString &name );
122 122
123 /** 123 /**
124 Returns the format name. 124 Returns the format name.
125 */ 125 */
126 QString format() const; 126 QString format() const;
127 127
128 /** 128 /**
129 * Remove a addressee from its source. 129 * Remove a addressee from its source.
130 * This method is mainly called by KABC::AddressBook. 130 * This method is mainly called by KABC::AddressBook.
131 */ 131 */
132 virtual void removeAddressee( const Addressee& addr ); 132 virtual void removeAddressee( const Addressee& addr );
133 133
134 /** 134 /**
135 * This method is called by an error handler if the application 135 * This method is called by an error handler if the application
136 * crashed 136 * crashed
137 */ 137 */
138 virtual void cleanUp(); 138 virtual void cleanUp();
139 139
140protected slots: 140protected slots:
141 void fileChanged(); 141 void fileChanged();
142 142
143protected: 143protected:
144 void init( const QString &fileName, const QString &format ); 144 void init( const QString &fileName, const QString &format );
145 145
146 bool lock( const QString &fileName ); 146 bool lock( const QString &fileName );
147 void unlock( const QString &fileName ); 147 void unlock( const QString &fileName );
148 148
149private: 149private:
150 int mLastBackupDate;
150 QString mFamily; 151 QString mFamily;
151 QString mFileName2; 152 QString mFileName2;
152 QString mFormatName; 153 QString mFormatName;
153 154
154 FormatPlugin *mFormat; 155 FormatPlugin *mFormat;
155 156
156 QString mLockUniqueName; 157 QString mLockUniqueName;
157#ifndef NO_DIRWATCH 158#ifndef NO_DIRWATCH
158 KDirWatch mDirWatch; 159 KDirWatch mDirWatch;
159#endif 160#endif
160}; 161};
161 162
162} 163}
163 164
164#endif 165#endif
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 61f2616..36b0df5 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,1965 +1,2010 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager 14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
18 **************************************************************************/ 18 **************************************************************************/
19 19
20#include "pwmdoc.h" 20#include "pwmdoc.h"
21#include "pwmview.h" 21#include "pwmview.h"
22#include "blowfish.h" 22#include "blowfish.h"
23#include "sha1.h" 23#include "sha1.h"
24#include "globalstuff.h" 24#include "globalstuff.h"
25#include "gpasmanfile.h" 25#include "gpasmanfile.h"
26#include "serializer.h" 26#include "serializer.h"
27#include "compressgzip.h" 27#include "compressgzip.h"
28//US#include "compressbzip2.h" 28//US#include "compressbzip2.h"
29#include "randomizer.h" 29#include "randomizer.h"
30#include "pwminit.h" 30#include "pwminit.h"
31#include "libgcryptif.h" 31#include "libgcryptif.h"
32#ifdef PWM_EMBEDDED 32#ifdef PWM_EMBEDDED
33#include "pwmprefs.h" 33#include "pwmprefs.h"
34#include "kglobal.h" 34#include "kglobal.h"
35#endif 35#endif
36 36
37#include <kmessagebox.h> 37#include <kmessagebox.h>
38#include <kconfig.h>
39#include <kglobalsettings.h>
38#include <libkcal/syncdefines.h> 40#include <libkcal/syncdefines.h>
39 41
40 42
41#ifdef CONFIG_KWALLETIF 43#ifdef CONFIG_KWALLETIF
42# include "kwalletemu.h" 44# include "kwalletemu.h"
43#endif // CONFIG_KWALLETIF 45#endif // CONFIG_KWALLETIF
44 46
45#include <qdatetime.h> 47#include <qdatetime.h>
46#include <qsize.h> 48#include <qsize.h>
47#include <qfileinfo.h> 49#include <qfileinfo.h>
48#include <qfile.h> 50#include <qfile.h>
49 51
50#include <stdio.h> 52#include <stdio.h>
51#include <stdlib.h> 53#include <stdlib.h>
52#include <errno.h> 54#include <errno.h>
53#include <string.h> 55#include <string.h>
54//US#include <iostream> 56//US#include <iostream>
55#include <algorithm> 57#include <algorithm>
56#include <sys/types.h> 58#include <sys/types.h>
57#include <sys/stat.h> 59#include <sys/stat.h>
58#ifndef _WIN32_ 60#ifndef _WIN32_
59#include <unistd.h> 61#include <unistd.h>
60#include <stdint.h> 62#include <stdint.h>
61#endif 63#endif
62 64
63#ifdef PWM_EMBEDDED 65#ifdef PWM_EMBEDDED
64#ifndef Q_LONG 66#ifndef Q_LONG
65#define Q_LONG long 67#define Q_LONG long
66#endif 68#endif
67 69
68#ifndef Q_ULONG 70#ifndef Q_ULONG
69#define Q_ULONG unsigned long 71#define Q_ULONG unsigned long
70#endif 72#endif
71#endif //PWM_EMBEDDED 73#endif //PWM_EMBEDDED
72 74
73 75
74//TODO: reset to its normal value. 76//TODO: reset to its normal value.
75//LR set to 5 min 77//LR set to 5 min
76 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */ 78 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */
77 79
78using namespace std; 80using namespace std;
79 81
80 82
81void PwMDocList::add(PwMDoc *doc, const string &id) 83void PwMDocList::add(PwMDoc *doc, const string &id)
82{ 84{
83#ifdef PWM_DEBUG 85#ifdef PWM_DEBUG
84 // check for existance of object in debug mode only. 86 // check for existance of object in debug mode only.
85 vector<listItem>::iterator begin = docList.begin(), 87 vector<listItem>::iterator begin = docList.begin(),
86 end = docList.end(), 88 end = docList.end(),
87 i = begin; 89 i = begin;
88 while (i != end) { 90 while (i != end) {
89 if (i->doc == doc) { 91 if (i->doc == doc) {
90 BUG(); 92 BUG();
91 return; 93 return;
92 } 94 }
93 ++i; 95 ++i;
94 } 96 }
95#endif 97#endif
96 listItem newItem; 98 listItem newItem;
97 newItem.doc = doc; 99 newItem.doc = doc;
98 newItem.docId = id; 100 newItem.docId = id;
99 docList.push_back(newItem); 101 docList.push_back(newItem);
100} 102}
101 103
102void PwMDocList::edit(PwMDoc *doc, const string &newId) 104void PwMDocList::edit(PwMDoc *doc, const string &newId)
103{ 105{
104 vector<listItem>::iterator begin = docList.begin(), 106 vector<listItem>::iterator begin = docList.begin(),
105 end = docList.end(), 107 end = docList.end(),
106 i = begin; 108 i = begin;
107 while (i != end) { 109 while (i != end) {
108 if (i->doc == doc) { 110 if (i->doc == doc) {
109 i->docId = newId; 111 i->docId = newId;
110 return; 112 return;
111 } 113 }
112 ++i; 114 ++i;
113 } 115 }
114} 116}
115 117
116void PwMDocList::del(PwMDoc *doc) 118void PwMDocList::del(PwMDoc *doc)
117{ 119{
118 vector<listItem>::iterator begin = docList.begin(), 120 vector<listItem>::iterator begin = docList.begin(),
119 end = docList.end(), 121 end = docList.end(),
120 i = begin; 122 i = begin;
121 while (i != end) { 123 while (i != end) {
122 if (i->doc == doc) { 124 if (i->doc == doc) {
123 docList.erase(i); 125 docList.erase(i);
124 return; 126 return;
125 } 127 }
126 ++i; 128 ++i;
127 } 129 }
128} 130}
129 131
130bool PwMDocList::find(const string &id, listItem *ret) 132bool PwMDocList::find(const string &id, listItem *ret)
131{ 133{
132 vector<listItem>::iterator begin = docList.begin(), 134 vector<listItem>::iterator begin = docList.begin(),
133 end = docList.end(), 135 end = docList.end(),
134 i = begin; 136 i = begin;
135 while (i != end) { 137 while (i != end) {
136 if (i->docId == id) { 138 if (i->docId == id) {
137 if (ret) 139 if (ret)
138 *ret = *i; 140 *ret = *i;
139 return true; 141 return true;
140 } 142 }
141 ++i; 143 ++i;
142 } 144 }
143 return false; 145 return false;
144} 146}
145 147
146 148
147 149
148DocTimer::DocTimer(PwMDoc *_doc) 150DocTimer::DocTimer(PwMDoc *_doc)
149 : doc (_doc) 151 : doc (_doc)
150 , mpwLock (0) 152 , mpwLock (0)
151 , autoLockLock (0) 153 , autoLockLock (0)
152 , metaCheckLock (0) 154 , metaCheckLock (0)
153{ 155{
154 mpwTimer = new QTimer; 156 mpwTimer = new QTimer;
155 autoLockTimer = new QTimer; 157 autoLockTimer = new QTimer;
156 metaCheckTimer = new QTimer; 158 metaCheckTimer = new QTimer;
157 connect(mpwTimer, SIGNAL(timeout()), 159 connect(mpwTimer, SIGNAL(timeout()),
158 this, SLOT(mpwTimeout())); 160 this, SLOT(mpwTimeout()));
159 connect(autoLockTimer, SIGNAL(timeout()), 161 connect(autoLockTimer, SIGNAL(timeout()),
160 this, SLOT(autoLockTimeout())); 162 this, SLOT(autoLockTimeout()));
161 connect(metaCheckTimer, SIGNAL(timeout()), 163 connect(metaCheckTimer, SIGNAL(timeout()),
162 this, SLOT(metaCheckTimeout())); 164 this, SLOT(metaCheckTimeout()));
163} 165}
164 166
165DocTimer::~DocTimer() 167DocTimer::~DocTimer()
166{ 168{
167 delete mpwTimer; 169 delete mpwTimer;
168 delete autoLockTimer; 170 delete autoLockTimer;
169 delete metaCheckTimer; 171 delete metaCheckTimer;
170} 172}
171 173
172void DocTimer::start(TimerIDs timer) 174void DocTimer::start(TimerIDs timer)
173{ 175{
174 switch (timer) { 176 switch (timer) {
175 case id_mpwTimer: 177 case id_mpwTimer:
176 if (mpwTimer->isActive()) 178 if (mpwTimer->isActive())
177 mpwTimer->stop(); 179 mpwTimer->stop();
178 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 180 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
179 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); 181 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
180 break; 182 break;
181 case id_autoLockTimer: 183 case id_autoLockTimer:
182 if (autoLockTimer->isActive()) 184 if (autoLockTimer->isActive())
183 autoLockTimer->stop(); 185 autoLockTimer->stop();
184 if (conf()->confGlobLockTimeout() > 0) 186 if (conf()->confGlobLockTimeout() > 0)
185 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); 187 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
186 break; 188 break;
187 case id_metaCheckTimer: 189 case id_metaCheckTimer:
188 if (metaCheckTimer->isActive()) 190 if (metaCheckTimer->isActive())
189 metaCheckTimer->stop(); 191 metaCheckTimer->stop();
190 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 192 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
191 break; 193 break;
192 } 194 }
193} 195}
194 196
195void DocTimer::stop(TimerIDs timer) 197void DocTimer::stop(TimerIDs timer)
196{ 198{
197 switch (timer) { 199 switch (timer) {
198 case id_mpwTimer: 200 case id_mpwTimer:
199 mpwTimer->stop(); 201 mpwTimer->stop();
200 break; 202 break;
201 case id_autoLockTimer: 203 case id_autoLockTimer:
202 autoLockTimer->stop(); 204 autoLockTimer->stop();
203 break; 205 break;
204 case id_metaCheckTimer: 206 case id_metaCheckTimer:
205 metaCheckTimer->stop(); 207 metaCheckTimer->stop();
206 break; 208 break;
207 } 209 }
208} 210}
209 211
210void DocTimer::getLock(TimerIDs timer) 212void DocTimer::getLock(TimerIDs timer)
211{ 213{
212 switch (timer) { 214 switch (timer) {
213 case id_mpwTimer: 215 case id_mpwTimer:
214 ++mpwLock; 216 ++mpwLock;
215 break; 217 break;
216 case id_autoLockTimer: 218 case id_autoLockTimer:
217 ++autoLockLock; 219 ++autoLockLock;
218 break; 220 break;
219 case id_metaCheckTimer: 221 case id_metaCheckTimer:
220 ++metaCheckLock; 222 ++metaCheckLock;
221 break; 223 break;
222 } 224 }
223} 225}
224 226
225void DocTimer::putLock(TimerIDs timer) 227void DocTimer::putLock(TimerIDs timer)
226{ 228{
227 switch (timer) { 229 switch (timer) {
228 case id_mpwTimer: 230 case id_mpwTimer:
229 if (mpwLock) 231 if (mpwLock)
230 --mpwLock; 232 --mpwLock;
231 break; 233 break;
232 case id_autoLockTimer: 234 case id_autoLockTimer:
233 if (autoLockLock) 235 if (autoLockLock)
234 --autoLockLock; 236 --autoLockLock;
235 break; 237 break;
236 case id_metaCheckTimer: 238 case id_metaCheckTimer:
237 if (metaCheckLock) 239 if (metaCheckLock)
238 --metaCheckLock; 240 --metaCheckLock;
239 break; 241 break;
240 } 242 }
241} 243}
242 244
243void DocTimer::mpwTimeout() 245void DocTimer::mpwTimeout()
244{ 246{
245 if (mpwLock) { 247 if (mpwLock) {
246 mpwTimer->start(1000, true); 248 mpwTimer->start(1000, true);
247 return; 249 return;
248 } 250 }
249 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 251 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
250} 252}
251 253
252void DocTimer::autoLockTimeout() 254void DocTimer::autoLockTimeout()
253{ 255{
254 if (autoLockLock) { 256 if (autoLockLock) {
255 autoLockTimer->start(1000, true); 257 autoLockTimer->start(1000, true);
256 return; 258 return;
257 } 259 }
258 if (conf()->confGlobAutoDeepLock() && 260 if (conf()->confGlobAutoDeepLock() &&
259 doc->filename != QString::null && 261 doc->filename != QString::null &&
260 doc->filename != "") { 262 doc->filename != "") {
261 doc->deepLock(true); 263 doc->deepLock(true);
262 } else { 264 } else {
263 doc->lockAll(true); 265 doc->lockAll(true);
264 } 266 }
265} 267}
266 268
267void DocTimer::metaCheckTimeout() 269void DocTimer::metaCheckTimeout()
268{ 270{
269 if (metaCheckLock) { 271 if (metaCheckLock) {
270 // check again in one second. 272 // check again in one second.
271 metaCheckTimer->start(1000, true); 273 metaCheckTimer->start(1000, true);
272 return; 274 return;
273 } 275 }
274 if (doc->isDeepLocked()) { 276 if (doc->isDeepLocked()) {
275 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 277 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
276 return; 278 return;
277 } 279 }
278 if (doc->isDocEmpty()) { 280 if (doc->isDocEmpty()) {
279 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 281 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
280 return; 282 return;
281 } 283 }
282#ifdef CONFIG_KWALLETIF 284#ifdef CONFIG_KWALLETIF
283 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 285 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
284 if (kwlEmu) 286 if (kwlEmu)
285 kwlEmu->suspendDocSignals(); 287 kwlEmu->suspendDocSignals();
286#endif // CONFIG_KWALLETIF 288#endif // CONFIG_KWALLETIF
287 /* We simply trigger all views to update their 289 /* We simply trigger all views to update their
288 * displayed values. This way they have a chance 290 * displayed values. This way they have a chance
289 * to get notified when some meta changes over time. 291 * to get notified when some meta changes over time.
290 * (for example an entry expired). 292 * (for example an entry expired).
291 * The _view_ is responsive for not updating its 293 * The _view_ is responsive for not updating its
292 * contents if nothing really changed! 294 * contents if nothing really changed!
293 */ 295 */
294 emit doc->dataChanged(doc); 296 emit doc->dataChanged(doc);
295#ifdef CONFIG_KWALLETIF 297#ifdef CONFIG_KWALLETIF
296 if (kwlEmu) 298 if (kwlEmu)
297 kwlEmu->resumeDocSignals(); 299 kwlEmu->resumeDocSignals();
298#endif // CONFIG_KWALLETIF 300#endif // CONFIG_KWALLETIF
299 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 301 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
300} 302}
301 303
302 304
303 305
304PwMDocList PwMDoc::openDocList; 306PwMDocList PwMDoc::openDocList;
305unsigned int PwMDocList::unnamedDocCnt = 1; 307unsigned int PwMDocList::unnamedDocCnt = 1;
306 308
307PwMDoc::PwMDoc(QObject *parent, const char *name) 309PwMDoc::PwMDoc(QObject *parent, const char *name)
308 : PwMDocUi(parent, name) 310 : PwMDocUi(parent, name)
309 , dataChangedLock (0) 311 , dataChangedLock (0)
310{ 312{
311 deleted = false; 313 deleted = false;
312 unnamedNum = 0; 314 unnamedNum = 0;
313 getOpenDocList()->add(this, getTitle().latin1()); 315 getOpenDocList()->add(this, getTitle().latin1());
314 curDocStat = 0; 316 curDocStat = 0;
315 setMaxNumEntries(); 317 setMaxNumEntries();
316 _timer = new DocTimer(this); 318 _timer = new DocTimer(this);
317 timer()->start(DocTimer::id_mpwTimer); 319 timer()->start(DocTimer::id_mpwTimer);
318 timer()->start(DocTimer::id_autoLockTimer); 320 timer()->start(DocTimer::id_autoLockTimer);
319 timer()->start(DocTimer::id_metaCheckTimer); 321 timer()->start(DocTimer::id_metaCheckTimer);
320 addCategory(DEFAULT_CATEGORY, 0, false); 322 addCategory(DEFAULT_CATEGORY, 0, false);
321 listView = 0; 323 listView = 0;
322 emit docCreated(this); 324 emit docCreated(this);
323} 325}
324 326
325PwMDoc::~PwMDoc() 327PwMDoc::~PwMDoc()
326{ 328{
327 emit docClosed(this); 329 emit docClosed(this);
328 getOpenDocList()->del(this); 330 getOpenDocList()->del(this);
329 delete _timer; 331 delete _timer;
330} 332}
331 333
332PwMerror PwMDoc::saveDoc(char compress, const QString *file) 334PwMerror PwMDoc::saveDoc(char compress, const QString *file)
333{ 335{
334 PwMerror ret, e; 336 PwMerror ret, e;
335 string serialized; 337 string serialized;
336 QFile f; 338 QFile f;
337 QString tmpFileMoved(QString::null); 339 QString tmpFileMoved(QString::null);
338 bool wasDeepLocked; 340 bool wasDeepLocked;
339 QString savedFilename(filename); 341 QString savedFilename(filename);
340 342
341 if (!file) { 343 if (!file) {
342 if (filename == "") 344 if (filename == "")
343 return e_filename; 345 return e_filename;
344 if (isDeepLocked()) { 346 if (isDeepLocked()) {
345 /* We don't need to save any data. 347 /* We don't need to save any data.
346 * It's already all on disk, because 348 * It's already all on disk, because
347 * we are deeplocked. 349 * we are deeplocked.
348 */ 350 */
349 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 351 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
350 ret = e_success; 352 ret = e_success;
351 return ret; 353 return ret;
352 } 354 }
353 } else { 355 } else {
354 if (*file == "" && filename == "") 356 if (*file == "" && filename == "")
355 return e_filename; 357 return e_filename;
356 if (*file != "") 358 if (*file != "")
357 filename = *file; 359 filename = *file;
358 } 360 }
359 361
360 wasDeepLocked = isDeepLocked(); 362 wasDeepLocked = isDeepLocked();
361 if (wasDeepLocked) { 363 if (wasDeepLocked) {
362 /* We are deeplocked. That means all data is already 364 /* We are deeplocked. That means all data is already
363 * on disk. BUT we need to do saving procedure, 365 * on disk. BUT we need to do saving procedure,
364 * because *file != savedFilename. 366 * because *file != savedFilename.
365 * Additionally we need to tempoarly restore 367 * Additionally we need to tempoarly restore
366 * the old "filename", because deepLock() references it. 368 * the old "filename", because deepLock() references it.
367 */ 369 */
368 QString newFilename(filename); 370 QString newFilename(filename);
369 filename = savedFilename; 371 filename = savedFilename;
370 getDataChangedLock(); 372 getDataChangedLock();
371 e = deepLock(false); 373 e = deepLock(false);
372 putDataChangedLock(); 374 putDataChangedLock();
373 filename = newFilename; 375 filename = newFilename;
374 switch (e) { 376 switch (e) {
375 case e_success: 377 case e_success:
376 break; 378 break;
377 case e_wrongPw: 379 case e_wrongPw:
378 case e_noPw: 380 case e_noPw:
379 emitDataChanged(this); 381 emitDataChanged(this);
380 return e; 382 return e;
381 default: 383 default:
382 emitDataChanged(this); 384 emitDataChanged(this);
383 return e_openFile; 385 return e_openFile;
384 } 386 }
385 } 387 }
386 388
387 if (!isPwAvailable()) { 389 if (!isPwAvailable()) {
388 /* password is not available. This means, the 390 /* password is not available. This means, the
389 * document wasn't saved, yet. 391 * document wasn't saved, yet.
390 */ 392 */
391 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 393 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
392 QString pw(requestNewMpw(&useChipcard)); 394 QString pw(requestNewMpw(&useChipcard));
393 if (pw != "") { 395 if (pw != "") {
394 currentPw = pw; 396 currentPw = pw;
395 } else { 397 } else {
396 return e_noPw; 398 return e_noPw;
397 } 399 }
398 if (useChipcard) { 400 if (useChipcard) {
399 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 401 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
400 } else { 402 } else {
401 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 403 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
402 } 404 }
403 } 405 }
404 406
405 int _cryptAlgo = conf()->confGlobCryptAlgo(); 407 int _cryptAlgo = conf()->confGlobCryptAlgo();
406 int _hashAlgo = conf()->confGlobHashAlgo(); 408 int _hashAlgo = conf()->confGlobHashAlgo();
407 409
408 // sanity check for the selected algorithms 410 // sanity check for the selected algorithms
409 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 411 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
410 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 412 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
411 printWarn("Invalid Crypto-Algorithm selected! " 413 printWarn("Invalid Crypto-Algorithm selected! "
412 "Config-file seems to be corrupt. " 414 "Config-file seems to be corrupt. "
413 "Falling back to Blowfish."); 415 "Falling back to Blowfish.");
414 _cryptAlgo = PWM_CRYPT_BLOWFISH; 416 _cryptAlgo = PWM_CRYPT_BLOWFISH;
415 } 417 }
416 if (_hashAlgo < PWM_HASH_SHA1 || 418 if (_hashAlgo < PWM_HASH_SHA1 ||
417 _hashAlgo > PWM_HASH_TIGER) { 419 _hashAlgo > PWM_HASH_TIGER) {
418 printWarn("Invalid Hash-Algorithm selected! " 420 printWarn("Invalid Hash-Algorithm selected! "
419 "Config-file seems to be corrupt. " 421 "Config-file seems to be corrupt. "
420 "Falling back to SHA1."); 422 "Falling back to SHA1.");
421 _hashAlgo = PWM_HASH_SHA1; 423 _hashAlgo = PWM_HASH_SHA1;
422 } 424 }
423 char cryptAlgo = static_cast<char>(_cryptAlgo); 425 char cryptAlgo = static_cast<char>(_cryptAlgo);
424 char hashAlgo = static_cast<char>(_hashAlgo); 426 char hashAlgo = static_cast<char>(_hashAlgo);
425 427
426 if (conf()->confGlobMakeFileBackup()) { 428 if (conf()->confGlobMakeFileBackup()) {
427 if (!backupFile(filename)) 429 if (!backupFile(filename))
428 return e_fileBackup; 430 return e_fileBackup;
429 } 431 }
432 int mLastBackupDate = 0;
433 KConfig configGlobal (locateLocal("config","pwmanagerbuprc"));
434 QFileInfo fileInfo ( filename );
435 mLastBackupDate = configGlobal.readNumEntry( "LastBackupDate-"+ fileInfo.fileName (), 0 );
436 KConfig config (locateLocal("config","microkdeglobalrc"));
437 config.setGroup( "BackupSettings" );
438 bool b_enabled = config.readBoolEntry( "BackupEnabled" );
439 if ( b_enabled ) {
440 int num = config.readNumEntry( "BackupNumbers" );
441 int d_count = config.readNumEntry( "BackupDayCount" );
442 bool stdDir = config.readBoolEntry( "BackupUseDefaultDir" );
443 QString bupDir = config.readEntry( "BackupDatadir" );
444 QDate reference ( 2000,1,1 );
445 int daysTo = reference.daysTo ( QDate::currentDate() );
446 bool saveDate = false;
447 if ( daysTo - d_count >= mLastBackupDate ) {
448 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
449 if ( stdDir )
450 bupDir = KGlobalSettings::backupDataDir();
451 int retval = KApplication::createBackup( filename, bupDir, num );
452 if ( retval == 0 ) {
453 qDebug("KO: Backup cancelled. Will try again tomorrow ");
454 // retval == 0 : backup skipped for today, try again tomorrow
455 mLastBackupDate = daysTo - d_count+1;
456 saveDate = true;
457 } else if ( retval == 1 ){
458 qDebug("KO: Backup created.");
459 // backup ok
460 mLastBackupDate = daysTo;
461 saveDate = true;
462 } else if ( retval == 2 ){
463 qDebug("KO: Backup globally cancelled.");
464 // backup globally cancelled
465 b_enabled = false;
466 }
467 if ( !b_enabled ) {
468 config.writeEntry( "mBackupEnabled", false );
469 }
470 if ( saveDate ) {
471 configGlobal.writeEntry( "LastBackupDate-"+ fileInfo.fileName (), mLastBackupDate );
472 }
473 }
474 }
430 if (QFile::exists(filename)) { 475 if (QFile::exists(filename)) {
431 /* Move the existing file to some tmp file. 476 /* Move the existing file to some tmp file.
432 * When saving file succeeds, delete tmp file. Otherwise 477 * When saving file succeeds, delete tmp file. Otherwise
433 * move tmp file back. See below. 478 * move tmp file back. See below.
434 */ 479 */
435 Randomizer *rnd = Randomizer::obj(); 480 Randomizer *rnd = Randomizer::obj();
436 char rnd_buf[5]; 481 char rnd_buf[5];
437 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 482 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
438 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 483 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
439 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 484 tmpFileMoved = filename + "." + rnd_buf + ".mv";
440 if (!copyFile(filename, tmpFileMoved)) 485 if (!copyFile(filename, tmpFileMoved))
441 return e_openFile; 486 return e_openFile;
442 if (!QFile::remove(filename)) { 487 if (!QFile::remove(filename)) {
443 printWarn(string("removing orig file ") 488 printWarn(string("removing orig file ")
444 + filename.latin1() 489 + filename.latin1()
445 + " failed!"); 490 + " failed!");
446 } 491 }
447 } 492 }
448 f.setName(filename); 493 f.setName(filename);
449 if (!f.open(IO_ReadWrite)) { 494 if (!f.open(IO_ReadWrite)) {
450 ret = e_openFile; 495 ret = e_openFile;
451 goto out_moveback; 496 goto out_moveback;
452 } 497 }
453 e = writeFileHeader(hashAlgo, hashAlgo, 498 e = writeFileHeader(hashAlgo, hashAlgo,
454 cryptAlgo, compress, 499 cryptAlgo, compress,
455 &currentPw, &f); 500 &currentPw, &f);
456 if (e == e_hashNotImpl) { 501 if (e == e_hashNotImpl) {
457 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 502 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
458 f.close(); 503 f.close();
459 ret = e_hashNotImpl; 504 ret = e_hashNotImpl;
460 goto out_moveback; 505 goto out_moveback;
461 } else if (e != e_success) { 506 } else if (e != e_success) {
462 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 507 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
463 f.close(); 508 f.close();
464 ret = e_writeHeader; 509 ret = e_writeHeader;
465 goto out_moveback; 510 goto out_moveback;
466 } 511 }
467 if (!serializeDta(&serialized)) { 512 if (!serializeDta(&serialized)) {
468 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 513 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
469 f.close(); 514 f.close();
470 ret = e_serializeDta; 515 ret = e_serializeDta;
471 goto out_moveback; 516 goto out_moveback;
472 } 517 }
473 e = writeDataHash(hashAlgo, &serialized, &f); 518 e = writeDataHash(hashAlgo, &serialized, &f);
474 if (e == e_hashNotImpl) { 519 if (e == e_hashNotImpl) {
475 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 520 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
476 f.close(); 521 f.close();
477 ret = e_hashNotImpl; 522 ret = e_hashNotImpl;
478 goto out_moveback; 523 goto out_moveback;
479 } else if (e != e_success) { 524 } else if (e != e_success) {
480 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 525 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
481 f.close(); 526 f.close();
482 ret = e_writeHeader; 527 ret = e_writeHeader;
483 goto out_moveback; 528 goto out_moveback;
484 } 529 }
485 if (!compressDta(&serialized, compress)) { 530 if (!compressDta(&serialized, compress)) {
486 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 531 printDebug("PwMDoc::saveDoc(): compressDta() failed");
487 f.close(); 532 f.close();
488 ret = e_enc; 533 ret = e_enc;
489 goto out_moveback; 534 goto out_moveback;
490 } 535 }
491 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo); 536 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
492 if (e == e_weakPw) { 537 if (e == e_weakPw) {
493 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 538 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
494 f.close(); 539 f.close();
495 ret = e_weakPw; 540 ret = e_weakPw;
496 goto out_moveback; 541 goto out_moveback;
497 } else if (e == e_cryptNotImpl) { 542 } else if (e == e_cryptNotImpl) {
498 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 543 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
499 f.close(); 544 f.close();
500 ret = e_cryptNotImpl; 545 ret = e_cryptNotImpl;
501 goto out_moveback; 546 goto out_moveback;
502 } else if (e != e_success) { 547 } else if (e != e_success) {
503 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 548 printDebug("PwMDoc::saveDoc(): encrypt() failed");
504 f.close(); 549 f.close();
505 ret = e_enc; 550 ret = e_enc;
506 goto out_moveback; 551 goto out_moveback;
507 } 552 }
508 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 553 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
509 f.close(); 554 f.close();
510#ifndef _WIN32_ 555#ifndef _WIN32_
511 if (chmod(filename.latin1(), 556 if (chmod(filename.latin1(),
512 conf()->confGlobFilePermissions())) { 557 conf()->confGlobFilePermissions())) {
513 printWarn(string("chmod failed: ") + strerror(errno)); 558 printWarn(string("chmod failed: ") + strerror(errno));
514 } 559 }
515#endif 560#endif
516 openDocList.edit(this, getTitle().latin1()); 561 openDocList.edit(this, getTitle().latin1());
517 if (wasDeepLocked) { 562 if (wasDeepLocked) {
518 /* Do _not_ save the data with the deepLock() 563 /* Do _not_ save the data with the deepLock()
519 * call, because this will recurse 564 * call, because this will recurse
520 * into saveDoc() 565 * into saveDoc()
521 */ 566 */
522 deepLock(true, false); 567 deepLock(true, false);
523 /* We don't check return value here, because 568 /* We don't check return value here, because
524 * it won't fail. See NOTE in deepLock() 569 * it won't fail. See NOTE in deepLock()
525 */ 570 */
526 } 571 }
527 if (tmpFileMoved != QString::null) { 572 if (tmpFileMoved != QString::null) {
528 // now remove the moved file. 573 // now remove the moved file.
529 if (!QFile::remove(tmpFileMoved)) { 574 if (!QFile::remove(tmpFileMoved)) {
530 printWarn(string("removing file ") 575 printWarn(string("removing file ")
531 + tmpFileMoved.latin1() 576 + tmpFileMoved.latin1()
532 + " failed!"); 577 + " failed!");
533 } 578 }
534 } 579 }
535 ret = e_success; 580 ret = e_success;
536 printDebug(string("writing file { name: ") 581 printDebug(string("writing file { name: ")
537 + filename.latin1() + " compress: " 582 + filename.latin1() + " compress: "
538 + tostr(static_cast<int>(compress)) + " cryptAlgo: " 583 + tostr(static_cast<int>(compress)) + " cryptAlgo: "
539 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " 584 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
540 + tostr(static_cast<int>(hashAlgo)) 585 + tostr(static_cast<int>(hashAlgo))
541 + " }"); 586 + " }");
542 goto out; 587 goto out;
543out_moveback: 588out_moveback:
544 if (tmpFileMoved != QString::null) { 589 if (tmpFileMoved != QString::null) {
545 if (copyFile(tmpFileMoved, filename)) { 590 if (copyFile(tmpFileMoved, filename)) {
546 if (!QFile::remove(tmpFileMoved)) { 591 if (!QFile::remove(tmpFileMoved)) {
547 printWarn(string("removing tmp file ") 592 printWarn(string("removing tmp file ")
548 + filename.latin1() 593 + filename.latin1()
549 + " failed!"); 594 + " failed!");
550 } 595 }
551 } else { 596 } else {
552 printWarn(string("couldn't copy file ") 597 printWarn(string("couldn't copy file ")
553 + tmpFileMoved.latin1() 598 + tmpFileMoved.latin1()
554 + " back to " 599 + " back to "
555 + filename.latin1()); 600 + filename.latin1());
556 } 601 }
557 } 602 }
558out: 603out:
559 return ret; 604 return ret;
560} 605}
561 606
562PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 607PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
563{ 608{
564 PWM_ASSERT(file); 609 PWM_ASSERT(file);
565 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 610 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
566 string decrypted, dataHash; 611 string decrypted, dataHash;
567 PwMerror ret; 612 PwMerror ret;
568 char cryptAlgo, dataHashType, compress; 613 char cryptAlgo, dataHashType, compress;
569 unsigned int headerLen; 614 unsigned int headerLen;
570 615
571 if (*file == "") 616 if (*file == "")
572 return e_readFile; 617 return e_readFile;
573 filename = *file; 618 filename = *file;
574 /* check if this file is already open. 619 /* check if this file is already open.
575 * This does not catch symlinks! 620 * This does not catch symlinks!
576 */ 621 */
577 if (!isDeepLocked()) { 622 if (!isDeepLocked()) {
578 if (getOpenDocList()->find(filename.latin1())) 623 if (getOpenDocList()->find(filename.latin1()))
579 return e_alreadyOpen; 624 return e_alreadyOpen;
580 } 625 }
581 QFile f(filename); 626 QFile f(filename);
582 627
583 if (openLocked == 2) { 628 if (openLocked == 2) {
584 // open deep-locked 629 // open deep-locked
585 if (!QFile::exists(filename)) 630 if (!QFile::exists(filename))
586 return e_openFile; 631 return e_openFile;
587 if (deepLock(true, false) != e_success) 632 if (deepLock(true, false) != e_success)
588 return e_openFile; 633 return e_openFile;
589 goto out_success; 634 goto out_success;
590 } 635 }
591 636
592 if (!f.open(IO_ReadOnly)) 637 if (!f.open(IO_ReadOnly))
593 return e_openFile; 638 return e_openFile;
594 639
595 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 640 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
596 &dataHashType, &dataHash, &f); 641 &dataHashType, &dataHash, &f);
597 if (ret != e_success) { 642 if (ret != e_success) {
598 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 643 printDebug("PwMDoc::openDoc(): checkHeader() failed");
599 f.close(); 644 f.close();
600 if (ret == e_wrongPw) { 645 if (ret == e_wrongPw) {
601 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 646 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
602 return ret; 647 return ret;
603 } else if (ret == e_noPw || 648 } else if (ret == e_noPw ||
604 ret == e_fileVer || 649 ret == e_fileVer ||
605 ret == e_fileFormat || 650 ret == e_fileFormat ||
606 ret == e_hashNotImpl) { 651 ret == e_hashNotImpl) {
607 return ret; 652 return ret;
608 } else 653 } else
609 return e_readFile; 654 return e_readFile;
610 } 655 }
611 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f); 656 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
612 if (ret == e_cryptNotImpl) { 657 if (ret == e_cryptNotImpl) {
613 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 658 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
614 f.close(); 659 f.close();
615 return e_cryptNotImpl; 660 return e_cryptNotImpl;
616 } else if (ret != e_success) { 661 } else if (ret != e_success) {
617 printDebug("PwMDoc::openDoc(): decrypt() failed"); 662 printDebug("PwMDoc::openDoc(): decrypt() failed");
618 f.close(); 663 f.close();
619 return e_readFile; 664 return e_readFile;
620 } 665 }
621 if (!decompressDta(&decrypted, compress)) { 666 if (!decompressDta(&decrypted, compress)) {
622 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 667 printDebug("PwMDoc::openDoc(): decompressDta() failed");
623 f.close(); 668 f.close();
624 return e_fileCorrupt; 669 return e_fileCorrupt;
625 } 670 }
626 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 671 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
627 if (ret == e_hashNotImpl) { 672 if (ret == e_hashNotImpl) {
628 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 673 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
629 f.close(); 674 f.close();
630 return e_hashNotImpl; 675 return e_hashNotImpl;
631 } else if (ret != e_success) { 676 } else if (ret != e_success) {
632 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 677 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
633 f.close(); 678 f.close();
634 return e_fileCorrupt; 679 return e_fileCorrupt;
635 } 680 }
636 if (!deSerializeDta(&decrypted, openLocked == 1)) { 681 if (!deSerializeDta(&decrypted, openLocked == 1)) {
637 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 682 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
638 f.close(); 683 f.close();
639 return e_readFile; 684 return e_readFile;
640 } 685 }
641 f.close(); 686 f.close();
642 timer()->start(DocTimer::id_mpwTimer); 687 timer()->start(DocTimer::id_mpwTimer);
643 timer()->start(DocTimer::id_autoLockTimer); 688 timer()->start(DocTimer::id_autoLockTimer);
644out_success: 689out_success:
645 openDocList.edit(this, getTitle().latin1()); 690 openDocList.edit(this, getTitle().latin1());
646 emit docOpened(this); 691 emit docOpened(this);
647 return e_success; 692 return e_success;
648} 693}
649 694
650PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 695PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
651 QString *pw, QFile *f) 696 QString *pw, QFile *f)
652{ 697{
653 PWM_ASSERT(pw); 698 PWM_ASSERT(pw);
654 PWM_ASSERT(f); 699 PWM_ASSERT(f);
655 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else 700 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
656 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion 701 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
657 //USPWM_ASSERT(listView); 702 //USPWM_ASSERT(listView);
658 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 703 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
659 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 704 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
660 return e_writeFile; 705 return e_writeFile;
661 } 706 }
662 if (f->putch(PWM_FILE_VER) == -1 || 707 if (f->putch(PWM_FILE_VER) == -1 ||
663 f->putch(keyHash) == -1 || 708 f->putch(keyHash) == -1 ||
664 f->putch(dataHash) == -1 || 709 f->putch(dataHash) == -1 ||
665 f->putch(crypt) == -1 || 710 f->putch(crypt) == -1 ||
666 f->putch(compress) == -1 || 711 f->putch(compress) == -1 ||
667 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 712 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
668 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 713 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
669 return e_writeFile; 714 return e_writeFile;
670 } 715 }
671 716
672 // write bytes of NUL-data. These bytes are reserved for future-use. 717 // write bytes of NUL-data. These bytes are reserved for future-use.
673 const int bufSize = 64; 718 const int bufSize = 64;
674 char tmp_buf[bufSize]; 719 char tmp_buf[bufSize];
675 memset(tmp_buf, 0x00, bufSize); 720 memset(tmp_buf, 0x00, bufSize);
676 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 721 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
677 return e_writeFile; 722 return e_writeFile;
678 723
679 switch (keyHash) { 724 switch (keyHash) {
680 case PWM_HASH_SHA1: { 725 case PWM_HASH_SHA1: {
681 const int hashlen = SHA1_HASH_LEN_BYTE; 726 const int hashlen = SHA1_HASH_LEN_BYTE;
682 Sha1 hash; 727 Sha1 hash;
683 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 728 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
684 string ret = hash.sha1_read(); 729 string ret = hash.sha1_read();
685 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 730 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
686 return e_writeFile; 731 return e_writeFile;
687 break; 732 break;
688 } 733 }
689 case PWM_HASH_SHA256: 734 case PWM_HASH_SHA256:
690 /*... fall through */ 735 /*... fall through */
691 case PWM_HASH_SHA384: 736 case PWM_HASH_SHA384:
692 case PWM_HASH_SHA512: 737 case PWM_HASH_SHA512:
693 case PWM_HASH_MD5: 738 case PWM_HASH_MD5:
694 case PWM_HASH_RMD160: 739 case PWM_HASH_RMD160:
695 case PWM_HASH_TIGER: 740 case PWM_HASH_TIGER:
696 { 741 {
697 if (!LibGCryptIf::available()) 742 if (!LibGCryptIf::available())
698 return e_hashNotImpl; 743 return e_hashNotImpl;
699 LibGCryptIf gc; 744 LibGCryptIf gc;
700 PwMerror err; 745 PwMerror err;
701 unsigned char *buf; 746 unsigned char *buf;
702 size_t hashLen; 747 size_t hashLen;
703 err = gc.hash(&buf, 748 err = gc.hash(&buf,
704 &hashLen, 749 &hashLen,
705 reinterpret_cast<const unsigned char *>(pw->latin1()), 750 reinterpret_cast<const unsigned char *>(pw->latin1()),
706 pw->length(), 751 pw->length(),
707 keyHash); 752 keyHash);
708 if (err != e_success) 753 if (err != e_success)
709 return e_hashNotImpl; 754 return e_hashNotImpl;
710 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 755 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
711 != static_cast<Q_LONG>(hashLen)) { 756 != static_cast<Q_LONG>(hashLen)) {
712 delete [] buf; 757 delete [] buf;
713 return e_hashNotImpl; 758 return e_hashNotImpl;
714 } 759 }
715 delete [] buf; 760 delete [] buf;
716 break; 761 break;
717 } 762 }
718 default: { 763 default: {
719 return e_hashNotImpl; 764 return e_hashNotImpl;
720 } } 765 } }
721 return e_success; 766 return e_success;
722} 767}
723 768
724PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 769PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
725 unsigned int *headerLength, char *dataHashType, 770 unsigned int *headerLength, char *dataHashType,
726 string *dataHash, QFile *f) 771 string *dataHash, QFile *f)
727{ 772{
728 PWM_ASSERT(cryptAlgo); 773 PWM_ASSERT(cryptAlgo);
729 PWM_ASSERT(pw); 774 PWM_ASSERT(pw);
730 PWM_ASSERT(headerLength); 775 PWM_ASSERT(headerLength);
731 PWM_ASSERT(dataHashType); 776 PWM_ASSERT(dataHashType);
732 PWM_ASSERT(dataHash); 777 PWM_ASSERT(dataHash);
733 PWM_ASSERT(f); 778 PWM_ASSERT(f);
734 int tmpRet; 779 int tmpRet;
735 // check "magic" header 780 // check "magic" header
736 const char magicHdr[] = FILE_ID_HEADER; 781 const char magicHdr[] = FILE_ID_HEADER;
737 const int hdrLen = array_size(magicHdr) - 1; 782 const int hdrLen = array_size(magicHdr) - 1;
738 char tmp[hdrLen]; 783 char tmp[hdrLen];
739 if (f->readBlock(tmp, hdrLen) != hdrLen) 784 if (f->readBlock(tmp, hdrLen) != hdrLen)
740 return e_readFile; 785 return e_readFile;
741 if (memcmp(tmp, magicHdr, hdrLen) != 0) 786 if (memcmp(tmp, magicHdr, hdrLen) != 0)
742 return e_fileFormat; 787 return e_fileFormat;
743 // read and check file ver 788 // read and check file ver
744 int fileV = f->getch(); 789 int fileV = f->getch();
745 if (fileV == -1) 790 if (fileV == -1)
746 return e_fileFormat; 791 return e_fileFormat;
747 if (fileV != PWM_FILE_VER) 792 if (fileV != PWM_FILE_VER)
748 return e_fileVer; 793 return e_fileVer;
749 // read hash hash type 794 // read hash hash type
750 int keyHash = f->getch(); 795 int keyHash = f->getch();
751 if (keyHash == -1) 796 if (keyHash == -1)
752 return e_fileFormat; 797 return e_fileFormat;
753 // read data hash type 798 // read data hash type
754 tmpRet = f->getch(); 799 tmpRet = f->getch();
755 if (tmpRet == -1) 800 if (tmpRet == -1)
756 return e_fileFormat; 801 return e_fileFormat;
757 *dataHashType = tmpRet; 802 *dataHashType = tmpRet;
758 // read crypt algo 803 // read crypt algo
759 tmpRet = f->getch(); 804 tmpRet = f->getch();
760 if (tmpRet == -1) 805 if (tmpRet == -1)
761 return e_fileFormat; 806 return e_fileFormat;
762 *cryptAlgo = tmpRet; 807 *cryptAlgo = tmpRet;
763 // get compression-algo 808 // get compression-algo
764 tmpRet = f->getch(); 809 tmpRet = f->getch();
765 if (tmpRet == -1) 810 if (tmpRet == -1)
766 return e_fileFormat; 811 return e_fileFormat;
767 *compress = tmpRet; 812 *compress = tmpRet;
768 // get the MPW-flag 813 // get the MPW-flag
769 int mpw_flag = f->getch(); 814 int mpw_flag = f->getch();
770 if (mpw_flag == -1) 815 if (mpw_flag == -1)
771 return e_fileFormat; 816 return e_fileFormat;
772 if (mpw_flag == 0x01) 817 if (mpw_flag == 0x01)
773 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 818 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
774 else 819 else
775 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 820 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
776 // skip the "RESERVED"-bytes 821 // skip the "RESERVED"-bytes
777 if (!(f->at(f->at() + 64))) 822 if (!(f->at(f->at() + 64)))
778 return e_fileFormat; 823 return e_fileFormat;
779 824
780 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 825 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
781 if (*pw == "") { 826 if (*pw == "") {
782 /* the user didn't give a master-password 827 /* the user didn't give a master-password
783 * or didn't insert a chipcard 828 * or didn't insert a chipcard
784 */ 829 */
785 return e_noPw; 830 return e_noPw;
786 } 831 }
787 // verify key-hash 832 // verify key-hash
788 switch (keyHash) { 833 switch (keyHash) {
789 case PWM_HASH_SHA1: { 834 case PWM_HASH_SHA1: {
790 // read hash from header 835 // read hash from header
791 const int hashLen = SHA1_HASH_LEN_BYTE; 836 const int hashLen = SHA1_HASH_LEN_BYTE;
792 string readHash; 837 string readHash;
793 int i; 838 int i;
794 for (i = 0; i < hashLen; ++i) 839 for (i = 0; i < hashLen; ++i)
795 readHash.push_back(f->getch()); 840 readHash.push_back(f->getch());
796 Sha1 hash; 841 Sha1 hash;
797 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 842 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
798 string ret = hash.sha1_read(); 843 string ret = hash.sha1_read();
799 if (ret != readHash) 844 if (ret != readHash)
800 return e_wrongPw;// hash doesn't match (wrong key) 845 return e_wrongPw;// hash doesn't match (wrong key)
801 break; 846 break;
802 } 847 }
803 case PWM_HASH_SHA256: 848 case PWM_HASH_SHA256:
804 /*... fall through */ 849 /*... fall through */
805 case PWM_HASH_SHA384: 850 case PWM_HASH_SHA384:
806 case PWM_HASH_SHA512: 851 case PWM_HASH_SHA512:
807 case PWM_HASH_MD5: 852 case PWM_HASH_MD5:
808 case PWM_HASH_RMD160: 853 case PWM_HASH_RMD160:
809 case PWM_HASH_TIGER: { 854 case PWM_HASH_TIGER: {
810 if (!LibGCryptIf::available()) 855 if (!LibGCryptIf::available())
811 return e_hashNotImpl; 856 return e_hashNotImpl;
812 LibGCryptIf gc; 857 LibGCryptIf gc;
813 PwMerror err; 858 PwMerror err;
814 unsigned char *buf; 859 unsigned char *buf;
815 size_t hashLen; 860 size_t hashLen;
816 err = gc.hash(&buf, 861 err = gc.hash(&buf,
817 &hashLen, 862 &hashLen,
818 reinterpret_cast<const unsigned char *>(pw->latin1()), 863 reinterpret_cast<const unsigned char *>(pw->latin1()),
819 pw->length(), 864 pw->length(),
820 keyHash); 865 keyHash);
821 if (err != e_success) 866 if (err != e_success)
822 return e_hashNotImpl; 867 return e_hashNotImpl;
823 string calcHash(reinterpret_cast<const char *>(buf), 868 string calcHash(reinterpret_cast<const char *>(buf),
824 static_cast<string::size_type>(hashLen)); 869 static_cast<string::size_type>(hashLen));
825 delete [] buf; 870 delete [] buf;
826 // read hash from header 871 // read hash from header
827 string readHash; 872 string readHash;
828 size_t i; 873 size_t i;
829 for (i = 0; i < hashLen; ++i) 874 for (i = 0; i < hashLen; ++i)
830 readHash.push_back(f->getch()); 875 readHash.push_back(f->getch());
831 if (calcHash != readHash) 876 if (calcHash != readHash)
832 return e_wrongPw;// hash doesn't match (wrong key) 877 return e_wrongPw;// hash doesn't match (wrong key)
833 break; 878 break;
834 } 879 }
835 default: { 880 default: {
836 return e_hashNotImpl; 881 return e_hashNotImpl;
837 } } 882 } }
838 // read the data-hash from the file 883 // read the data-hash from the file
839 unsigned int hashLen, i; 884 unsigned int hashLen, i;
840 switch (*dataHashType) { 885 switch (*dataHashType) {
841 case PWM_HASH_SHA1: 886 case PWM_HASH_SHA1:
842 hashLen = SHA1_HASH_LEN_BYTE; 887 hashLen = SHA1_HASH_LEN_BYTE;
843 break; 888 break;
844 case PWM_HASH_SHA256: 889 case PWM_HASH_SHA256:
845 /*... fall through */ 890 /*... fall through */
846 case PWM_HASH_SHA384: 891 case PWM_HASH_SHA384:
847 case PWM_HASH_SHA512: 892 case PWM_HASH_SHA512:
848 case PWM_HASH_MD5: 893 case PWM_HASH_MD5:
849 case PWM_HASH_RMD160: 894 case PWM_HASH_RMD160:
850 case PWM_HASH_TIGER: { 895 case PWM_HASH_TIGER: {
851 if (!LibGCryptIf::available()) 896 if (!LibGCryptIf::available())
852 return e_hashNotImpl; 897 return e_hashNotImpl;
853 LibGCryptIf gc; 898 LibGCryptIf gc;
854 hashLen = gc.hashLength(*dataHashType); 899 hashLen = gc.hashLength(*dataHashType);
855 if (hashLen == 0) 900 if (hashLen == 0)
856 return e_hashNotImpl; 901 return e_hashNotImpl;
857 break; 902 break;
858 } 903 }
859 default: 904 default:
860 return e_hashNotImpl; 905 return e_hashNotImpl;
861 } 906 }
862 *dataHash = ""; 907 *dataHash = "";
863 for (i = 0; i < hashLen; ++i) { 908 for (i = 0; i < hashLen; ++i) {
864 tmpRet = f->getch(); 909 tmpRet = f->getch();
865 if (tmpRet == -1) 910 if (tmpRet == -1)
866 return e_fileFormat; 911 return e_fileFormat;
867 dataHash->push_back(static_cast<char>(tmpRet)); 912 dataHash->push_back(static_cast<char>(tmpRet));
868 } 913 }
869 *headerLength = f->at(); 914 *headerLength = f->at();
870#ifndef PWM_EMBEDDED 915#ifndef PWM_EMBEDDED
871 printDebug(string("opening file { compress: ") 916 printDebug(string("opening file { compress: ")
872 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 917 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
873 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 918 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
874 + tostr(static_cast<int>(keyHash)) 919 + tostr(static_cast<int>(keyHash))
875 + " }"); 920 + " }");
876#else 921#else
877 printDebug(string("opening file { compress: ") 922 printDebug(string("opening file { compress: ")
878 + tostr((int)(*compress)) + " cryptAlgo: " 923 + tostr((int)(*compress)) + " cryptAlgo: "
879 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 924 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
880 + tostr((int)(keyHash)) 925 + tostr((int)(keyHash))
881 + " }"); 926 + " }");
882#endif 927#endif
883 928
884 return e_success; 929 return e_success;
885} 930}
886 931
887PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 932PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
888{ 933{
889 PWM_ASSERT(d); 934 PWM_ASSERT(d);
890 PWM_ASSERT(f); 935 PWM_ASSERT(f);
891 936
892 switch (dataHash) { 937 switch (dataHash) {
893 case PWM_HASH_SHA1: { 938 case PWM_HASH_SHA1: {
894 const int hashLen = SHA1_HASH_LEN_BYTE; 939 const int hashLen = SHA1_HASH_LEN_BYTE;
895 Sha1 h; 940 Sha1 h;
896 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 941 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
897 string hRet = h.sha1_read(); 942 string hRet = h.sha1_read();
898 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 943 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
899 return e_writeFile; 944 return e_writeFile;
900 break; 945 break;
901 } 946 }
902 case PWM_HASH_SHA256: 947 case PWM_HASH_SHA256:
903 /*... fall through */ 948 /*... fall through */
904 case PWM_HASH_SHA384: 949 case PWM_HASH_SHA384:
905 case PWM_HASH_SHA512: 950 case PWM_HASH_SHA512:
906 case PWM_HASH_MD5: 951 case PWM_HASH_MD5:
907 case PWM_HASH_RMD160: 952 case PWM_HASH_RMD160:
908 case PWM_HASH_TIGER: { 953 case PWM_HASH_TIGER: {
909 if (!LibGCryptIf::available()) 954 if (!LibGCryptIf::available())
910 return e_hashNotImpl; 955 return e_hashNotImpl;
911 LibGCryptIf gc; 956 LibGCryptIf gc;
912 PwMerror err; 957 PwMerror err;
913 unsigned char *buf; 958 unsigned char *buf;
914 size_t hashLen; 959 size_t hashLen;
915 err = gc.hash(&buf, 960 err = gc.hash(&buf,
916 &hashLen, 961 &hashLen,
917 reinterpret_cast<const unsigned char *>(d->c_str()), 962 reinterpret_cast<const unsigned char *>(d->c_str()),
918 d->size(), 963 d->size(),
919 dataHash); 964 dataHash);
920 if (err != e_success) 965 if (err != e_success)
921 return e_hashNotImpl; 966 return e_hashNotImpl;
922 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 967 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
923 != static_cast<Q_LONG>(hashLen)) { 968 != static_cast<Q_LONG>(hashLen)) {
924 delete [] buf; 969 delete [] buf;
925 return e_hashNotImpl; 970 return e_hashNotImpl;
926 } 971 }
927 delete [] buf; 972 delete [] buf;
928 break; 973 break;
929 } 974 }
930 default: { 975 default: {
931 return e_hashNotImpl; 976 return e_hashNotImpl;
932 } } 977 } }
933 978
934 return e_success; 979 return e_success;
935} 980}
936 981
937bool PwMDoc::backupFile(const QString &filePath) 982bool PwMDoc::backupFile(const QString &filePath)
938{ 983{
939 QFileInfo fi(filePath); 984 QFileInfo fi(filePath);
940 if (!fi.exists()) 985 if (!fi.exists())
941 return true; // Yes, true is correct. 986 return true; // Yes, true is correct.
942 QString pathOnly(fi.dirPath(true)); 987 QString pathOnly(fi.dirPath(true));
943 QString nameOnly(fi.fileName()); 988 QString nameOnly(fi.fileName());
944 QString backupPath = pathOnly 989 QString backupPath = pathOnly
945 + "/~" 990 + "/~"
946 + nameOnly 991 + nameOnly
947 + ".backup"; 992 + ".backup";
948 return copyFile(filePath, backupPath); 993 return copyFile(filePath, backupPath);
949} 994}
950 995
951bool PwMDoc::copyFile(const QString &src, const QString &dst) 996bool PwMDoc::copyFile(const QString &src, const QString &dst)
952{ 997{
953 QFileInfo fi(src); 998 QFileInfo fi(src);
954 if (!fi.exists()) 999 if (!fi.exists())
955 return false; 1000 return false;
956 if (QFile::exists(dst)) { 1001 if (QFile::exists(dst)) {
957 if (!QFile::remove(dst)) 1002 if (!QFile::remove(dst))
958 return false; 1003 return false;
959 } 1004 }
960 QFile srcFd(src); 1005 QFile srcFd(src);
961 if (!srcFd.open(IO_ReadOnly)) 1006 if (!srcFd.open(IO_ReadOnly))
962 return false; 1007 return false;
963 QFile dstFd(dst); 1008 QFile dstFd(dst);
964 if (!dstFd.open(IO_ReadWrite)) { 1009 if (!dstFd.open(IO_ReadWrite)) {
965 srcFd.close(); 1010 srcFd.close();
966 return false; 1011 return false;
967 } 1012 }
968 const int tmpBuf_size = 512; 1013 const int tmpBuf_size = 512;
969 char tmpBuf[tmpBuf_size]; 1014 char tmpBuf[tmpBuf_size];
970 Q_LONG bytesRead, bytesWritten; 1015 Q_LONG bytesRead, bytesWritten;
971 1016
972 while (!srcFd.atEnd()) { 1017 while (!srcFd.atEnd()) {
973 bytesRead = srcFd.readBlock(tmpBuf, 1018 bytesRead = srcFd.readBlock(tmpBuf,
974 static_cast<Q_ULONG>(tmpBuf_size)); 1019 static_cast<Q_ULONG>(tmpBuf_size));
975 if (bytesRead == -1) { 1020 if (bytesRead == -1) {
976 srcFd.close(); 1021 srcFd.close();
977 dstFd.close(); 1022 dstFd.close();
978 return false; 1023 return false;
979 } 1024 }
980 bytesWritten = dstFd.writeBlock(tmpBuf, 1025 bytesWritten = dstFd.writeBlock(tmpBuf,
981 static_cast<Q_ULONG>(bytesRead)); 1026 static_cast<Q_ULONG>(bytesRead));
982 if (bytesWritten != bytesRead) { 1027 if (bytesWritten != bytesRead) {
983 srcFd.close(); 1028 srcFd.close();
984 dstFd.close(); 1029 dstFd.close();
985 return false; 1030 return false;
986 } 1031 }
987 } 1032 }
988 srcFd.close(); 1033 srcFd.close();
989 dstFd.close(); 1034 dstFd.close();
990 return true; 1035 return true;
991} 1036}
992 1037
993PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 1038PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
994 bool dontFlagDirty, bool updateMeta) 1039 bool dontFlagDirty, bool updateMeta)
995{ 1040{
996 PWM_ASSERT(d); 1041 PWM_ASSERT(d);
997 unsigned int cat = 0; 1042 unsigned int cat = 0;
998 1043
999 if (isDeepLocked()) { 1044 if (isDeepLocked()) {
1000 PwMerror ret; 1045 PwMerror ret;
1001 ret = deepLock(false); 1046 ret = deepLock(false);
1002 if (ret != e_success) 1047 if (ret != e_success)
1003 return e_lock; 1048 return e_lock;
1004 } 1049 }
1005 1050
1006 addCategory(category, &cat); 1051 addCategory(category, &cat);
1007 1052
1008 if (numEntries(category) >= maxEntries) 1053 if (numEntries(category) >= maxEntries)
1009 return e_maxAllowedEntr; 1054 return e_maxAllowedEntr;
1010 1055
1011 vector<unsigned int> foundPositions; 1056 vector<unsigned int> foundPositions;
1012 /* historically this was: 1057 /* historically this was:
1013 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 1058 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
1014 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 1059 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
1015 * But for now we only search in desc. 1060 * But for now we only search in desc.
1016 * That's a tweak to be KWallet compatible. But it should not add 1061 * That's a tweak to be KWallet compatible. But it should not add
1017 * usability-drop onto PwManager, does it? 1062 * usability-drop onto PwManager, does it?
1018 * (And yes, "int" was a bug. Correct is "unsigned int") 1063 * (And yes, "int" was a bug. Correct is "unsigned int")
1019 */ 1064 */
1020 const unsigned int searchIn = SEARCH_IN_DESC; 1065 const unsigned int searchIn = SEARCH_IN_DESC;
1021 findEntry(cat, *d, searchIn, &foundPositions, true); 1066 findEntry(cat, *d, searchIn, &foundPositions, true);
1022 if (foundPositions.size()) { 1067 if (foundPositions.size()) {
1023 // DOH! We found this entry. 1068 // DOH! We found this entry.
1024 return e_entryExists; 1069 return e_entryExists;
1025 } 1070 }
1026 1071
1027 d->listViewPos = -1; 1072 d->listViewPos = -1;
1028 d->lockStat = conf()->confGlobNewEntrLockStat(); 1073 d->lockStat = conf()->confGlobNewEntrLockStat();
1029 if (updateMeta) { 1074 if (updateMeta) {
1030 d->meta.create = QDateTime::currentDateTime(); 1075 d->meta.create = QDateTime::currentDateTime();
1031 d->meta.update = d->meta.create; 1076 d->meta.update = d->meta.create;
1032 } 1077 }
1033 dti.dta[cat].d.push_back(*d); 1078 dti.dta[cat].d.push_back(*d);
1034 1079
1035 delAllEmptyCat(true); 1080 delAllEmptyCat(true);
1036 1081
1037 if (!dontFlagDirty) 1082 if (!dontFlagDirty)
1038 flagDirty(); 1083 flagDirty();
1039 return e_success; 1084 return e_success;
1040} 1085}
1041 1086
1042PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 1087PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
1043 bool checkIfExist) 1088 bool checkIfExist)
1044{ 1089{
1045 if (isDeepLocked()) { 1090 if (isDeepLocked()) {
1046 PwMerror ret; 1091 PwMerror ret;
1047 ret = deepLock(false); 1092 ret = deepLock(false);
1048 if (ret != e_success) 1093 if (ret != e_success)
1049 return e_lock; 1094 return e_lock;
1050 } 1095 }
1051 if (checkIfExist) { 1096 if (checkIfExist) {
1052 if (findCategory(category, categoryIndex)) 1097 if (findCategory(category, categoryIndex))
1053 return e_categoryExists; 1098 return e_categoryExists;
1054 } 1099 }
1055 PwMCategoryItem item; 1100 PwMCategoryItem item;
1056 //US ENH: clear item to initialize with default values, or create a constructor 1101 //US ENH: clear item to initialize with default values, or create a constructor
1057 item.clear(); 1102 item.clear();
1058 1103
1059 item.name = category.latin1(); 1104 item.name = category.latin1();
1060 dti.dta.push_back(item); 1105 dti.dta.push_back(item);
1061 if (categoryIndex) 1106 if (categoryIndex)
1062 *categoryIndex = dti.dta.size() - 1; 1107 *categoryIndex = dti.dta.size() - 1;
1063 return e_success; 1108 return e_success;
1064} 1109}
1065 1110
1066bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1111bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1067{ 1112{
1068 unsigned int cat = 0; 1113 unsigned int cat = 0;
1069 1114
1070 if (!findCategory(category, &cat)) { 1115 if (!findCategory(category, &cat)) {
1071 BUG(); 1116 BUG();
1072 return false; 1117 return false;
1073 } 1118 }
1074 1119
1075 return delEntry(cat, index, dontFlagDirty); 1120 return delEntry(cat, index, dontFlagDirty);
1076} 1121}
1077 1122
1078bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1123bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1079{ 1124{
1080 if (isDeepLocked()) 1125 if (isDeepLocked())
1081 return false; 1126 return false;
1082 if (index > dti.dta[category].d.size() - 1) 1127 if (index > dti.dta[category].d.size() - 1)
1083 return false; 1128 return false;
1084 getDataChangedLock(); 1129 getDataChangedLock();
1085 if (!lockAt(category, index, false)) { 1130 if (!lockAt(category, index, false)) {
1086 putDataChangedLock(); 1131 putDataChangedLock();
1087 return false; 1132 return false;
1088 } 1133 }
1089 putDataChangedLock(); 1134 putDataChangedLock();
1090 int lvPos = dti.dta[category].d[index].listViewPos; 1135 int lvPos = dti.dta[category].d[index].listViewPos;
1091 1136
1092 // delete entry 1137 // delete entry
1093 dti.dta[category].d.erase(dti.dta[category].d.begin() + index); 1138 dti.dta[category].d.erase(dti.dta[category].d.begin() + index);
1094 1139
1095 unsigned int i, entries = numEntries(category); 1140 unsigned int i, entries = numEntries(category);
1096 if (!entries) { 1141 if (!entries) {
1097 // no more entries in this category, so 1142 // no more entries in this category, so
1098 // we can delete it, too. 1143 // we can delete it, too.
1099 BUG_ON(!delCategory(category)); 1144 BUG_ON(!delCategory(category));
1100 // delCategory() flags it dirty, so we need not to do so. 1145 // delCategory() flags it dirty, so we need not to do so.
1101 return true; 1146 return true;
1102 } 1147 }
1103 for (i = 0; i < entries; ++i) { 1148 for (i = 0; i < entries; ++i) {
1104 // decrement all listViewPositions that are greater than the deleted. 1149 // decrement all listViewPositions that are greater than the deleted.
1105 if (dti.dta[category].d[i].listViewPos > lvPos) 1150 if (dti.dta[category].d[i].listViewPos > lvPos)
1106 --dti.dta[category].d[i].listViewPos; 1151 --dti.dta[category].d[i].listViewPos;
1107 } 1152 }
1108 1153
1109 if (!dontFlagDirty) 1154 if (!dontFlagDirty)
1110 flagDirty(); 1155 flagDirty();
1111 return true; 1156 return true;
1112} 1157}
1113 1158
1114bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, 1159bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory,
1115 unsigned int index, PwMDataItem *d, bool updateMeta) 1160 unsigned int index, PwMDataItem *d, bool updateMeta)
1116{ 1161{
1117 PWM_ASSERT(d); 1162 PWM_ASSERT(d);
1118 unsigned int oldCat = 0; 1163 unsigned int oldCat = 0;
1119 1164
1120 if (!findCategory(oldCategory, &oldCat)) { 1165 if (!findCategory(oldCategory, &oldCat)) {
1121 BUG(); 1166 BUG();
1122 return false; 1167 return false;
1123 } 1168 }
1124 1169
1125 return editEntry(oldCat, newCategory, index, d, updateMeta); 1170 return editEntry(oldCat, newCategory, index, d, updateMeta);
1126} 1171}
1127 1172
1128bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, 1173bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory,
1129 unsigned int index, PwMDataItem *d, bool updateMeta) 1174 unsigned int index, PwMDataItem *d, bool updateMeta)
1130{ 1175{
1131 if (isDeepLocked()) 1176 if (isDeepLocked())
1132 return false; 1177 return false;
1133 if (updateMeta) { 1178 if (updateMeta) {
1134 d->meta.update = QDateTime::currentDateTime(); 1179 d->meta.update = QDateTime::currentDateTime();
1135 if (d->meta.create.isNull()) { 1180 if (d->meta.create.isNull()) {
1136 d->meta.create = d->meta.update; 1181 d->meta.create = d->meta.update;
1137 } 1182 }
1138 } 1183 }
1139 if (dti.dta[oldCategory].name != newCategory.latin1()) { 1184 if (dti.dta[oldCategory].name != newCategory.latin1()) {
1140 // the user changed the category. 1185 // the user changed the category.
1141 PwMerror ret; 1186 PwMerror ret;
1142 d->rev = 0; 1187 d->rev = 0;
1143 ret = addEntry(newCategory, d, true, false); 1188 ret = addEntry(newCategory, d, true, false);
1144 if (ret != e_success) 1189 if (ret != e_success)
1145 return false; 1190 return false;
1146 if (!delEntry(oldCategory, index, true)) 1191 if (!delEntry(oldCategory, index, true))
1147 return false; 1192 return false;
1148 } else { 1193 } else {
1149 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter. 1194 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter.
1150 dti.dta[oldCategory].d[index] = *d; 1195 dti.dta[oldCategory].d[index] = *d;
1151 } 1196 }
1152 flagDirty(); 1197 flagDirty();
1153 return true; 1198 return true;
1154} 1199}
1155 1200
1156unsigned int PwMDoc::numEntries(const QString &category) 1201unsigned int PwMDoc::numEntries(const QString &category)
1157{ 1202{
1158 unsigned int cat = 0; 1203 unsigned int cat = 0;
1159 1204
1160 if (!findCategory(category, &cat)) { 1205 if (!findCategory(category, &cat)) {
1161 BUG(); 1206 BUG();
1162 return 0; 1207 return 0;
1163 } 1208 }
1164 1209
1165 return numEntries(cat); 1210 return numEntries(cat);
1166} 1211}
1167 1212
1168bool PwMDoc::serializeDta(string *d) 1213bool PwMDoc::serializeDta(string *d)
1169{ 1214{
1170 PWM_ASSERT(d); 1215 PWM_ASSERT(d);
1171 Serializer ser; 1216 Serializer ser;
1172 if (!ser.serialize(dti)) 1217 if (!ser.serialize(dti))
1173 return false; 1218 return false;
1174 d->assign(ser.getXml()); 1219 d->assign(ser.getXml());
1175 if (!d->size()) 1220 if (!d->size())
1176 return false; 1221 return false;
1177 return true; 1222 return true;
1178} 1223}
1179 1224
1180bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked) 1225bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked)
1181{ 1226{
1182 PWM_ASSERT(d); 1227 PWM_ASSERT(d);
1183#ifndef PWM_EMBEDDED 1228#ifndef PWM_EMBEDDED
1184 try { 1229 try {
1185 1230
1186 Serializer ser(d->c_str()); 1231 Serializer ser(d->c_str());
1187 ser.setDefaultLockStat(entriesLocked); 1232 ser.setDefaultLockStat(entriesLocked);
1188 if (!ser.deSerialize(&dti)) 1233 if (!ser.deSerialize(&dti))
1189 return false; 1234 return false;
1190 } catch (PwMException) { 1235 } catch (PwMException) {
1191 return false; 1236 return false;
1192 } 1237 }
1193#else 1238#else
1194 Serializer ser(d->c_str()); 1239 Serializer ser(d->c_str());
1195 ser.setDefaultLockStat(entriesLocked); 1240 ser.setDefaultLockStat(entriesLocked);
1196 if (!ser.deSerialize(&dti)) 1241 if (!ser.deSerialize(&dti))
1197 return false; 1242 return false;
1198#endif 1243#endif
1199 1244
1200 emitDataChanged(this); 1245 emitDataChanged(this);
1201 return true; 1246 return true;
1202} 1247}
1203 1248
1204bool PwMDoc::getEntry(const QString &category, unsigned int index, 1249bool PwMDoc::getEntry(const QString &category, unsigned int index,
1205 PwMDataItem * d, bool unlockIfLocked) 1250 PwMDataItem * d, bool unlockIfLocked)
1206{ 1251{
1207 PWM_ASSERT(d); 1252 PWM_ASSERT(d);
1208 unsigned int cat = 0; 1253 unsigned int cat = 0;
1209 1254
1210 if (!findCategory(category, &cat)) { 1255 if (!findCategory(category, &cat)) {
1211 BUG(); 1256 BUG();
1212 return false; 1257 return false;
1213 } 1258 }
1214 1259
1215 return getEntry(cat, index, d, unlockIfLocked); 1260 return getEntry(cat, index, d, unlockIfLocked);
1216} 1261}
1217 1262
1218bool PwMDoc::getEntry(unsigned int category, unsigned int index, 1263bool PwMDoc::getEntry(unsigned int category, unsigned int index,
1219 PwMDataItem *d, bool unlockIfLocked) 1264 PwMDataItem *d, bool unlockIfLocked)
1220{ 1265{
1221 if (index > dti.dta[category].d.size() - 1) 1266 if (index > dti.dta[category].d.size() - 1)
1222 return false; 1267 return false;
1223 1268
1224 bool locked = isLocked(category, index); 1269 bool locked = isLocked(category, index);
1225 if (locked) { 1270 if (locked) {
1226 /* this entry is locked. We don't return a password, 1271 /* this entry is locked. We don't return a password,
1227 * until it's unlocked by the user by inserting 1272 * until it's unlocked by the user by inserting
1228 * chipcard or entering the mpw 1273 * chipcard or entering the mpw
1229 */ 1274 */
1230 if (unlockIfLocked) { 1275 if (unlockIfLocked) {
1231 if (!lockAt(category, index, false)) { 1276 if (!lockAt(category, index, false)) {
1232 return false; 1277 return false;
1233 } 1278 }
1234 locked = false; 1279 locked = false;
1235 } 1280 }
1236 } 1281 }
1237 1282
1238 *d = dti.dta[category].d[index]; 1283 *d = dti.dta[category].d[index];
1239 if (locked) 1284 if (locked)
1240 d->pw = LOCKED_STRING.latin1(); 1285 d->pw = LOCKED_STRING.latin1();
1241 1286
1242 return true; 1287 return true;
1243} 1288}
1244PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, 1289PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos,
1245 string *foundComment) 1290 string *foundComment)
1246{ 1291{
1247 PWM_ASSERT(foundComment); 1292 PWM_ASSERT(foundComment);
1248 unsigned int cat = 0; 1293 unsigned int cat = 0;
1249 1294
1250 if (!findCategory(category, &cat)) 1295 if (!findCategory(category, &cat))
1251 return e_invalidArg; 1296 return e_invalidArg;
1252 1297
1253 unsigned int i, entries = numEntries(cat); 1298 unsigned int i, entries = numEntries(cat);
1254 for (i = 0; i < entries; ++i) { 1299 for (i = 0; i < entries; ++i) {
1255 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1300 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1256 *foundComment = dti.dta[cat].d[i].comment; 1301 *foundComment = dti.dta[cat].d[i].comment;
1257 if (dti.dta[cat].d[i].binary) 1302 if (dti.dta[cat].d[i].binary)
1258 return e_binEntry; 1303 return e_binEntry;
1259 return e_normalEntry; 1304 return e_normalEntry;
1260 } 1305 }
1261 } 1306 }
1262 BUG(); 1307 BUG();
1263 return e_generic; 1308 return e_generic;
1264} 1309}
1265 1310
1266PwMerror PwMDoc::getCommentByLvp_long(const QString &category, int listViewPos, 1311PwMerror PwMDoc::getCommentByLvp_long(const QString &category, int listViewPos,
1267 string *foundComment) 1312 string *foundComment)
1268{ 1313{
1269 PWM_ASSERT(foundComment); 1314 PWM_ASSERT(foundComment);
1270 unsigned int cat = 0; 1315 unsigned int cat = 0;
1271 1316
1272 if (!findCategory(category, &cat)) 1317 if (!findCategory(category, &cat))
1273 return e_invalidArg; 1318 return e_invalidArg;
1274 1319
1275 unsigned int i, entries = numEntries(cat); 1320 unsigned int i, entries = numEntries(cat);
1276 for (i = 0; i < entries; ++i) { 1321 for (i = 0; i < entries; ++i) {
1277 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1322 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1278 if (dti.dta[cat].d[i].binary) 1323 if (dti.dta[cat].d[i].binary)
1279 return e_binEntry; 1324 return e_binEntry;
1280 PwMCategoryItem* catItem = getCategoryEntry(cat); 1325 PwMCategoryItem* catItem = getCategoryEntry(cat);
1281 QString retval; 1326 QString retval;
1282 QString tempval = QString (dti.dta[cat].d[i].desc.c_str()); 1327 QString tempval = QString (dti.dta[cat].d[i].desc.c_str());
1283 if ( !tempval.isEmpty() ) { 1328 if ( !tempval.isEmpty() ) {
1284 retval += "<b>" +QString ( catItem->desc_text.c_str() )+ ":</b> "+ tempval+"<br>" ; 1329 retval += "<b>" +QString ( catItem->desc_text.c_str() )+ ":</b> "+ tempval+"<br>" ;
1285 } 1330 }
1286 tempval = QString (dti.dta[cat].d[i].name.c_str()); 1331 tempval = QString (dti.dta[cat].d[i].name.c_str());
1287 if ( !tempval.isEmpty() ) { 1332 if ( !tempval.isEmpty() ) {
1288 retval += "<b>" +QString ( catItem->name_text.c_str() ) + ":</b> "+ tempval+"<br>" ; 1333 retval += "<b>" +QString ( catItem->name_text.c_str() ) + ":</b> "+ tempval+"<br>" ;
1289 } 1334 }
1290 tempval = QString (dti.dta[cat].d[i].pw.c_str()); 1335 tempval = QString (dti.dta[cat].d[i].pw.c_str());
1291 if ( !tempval.isEmpty() ) { 1336 if ( !tempval.isEmpty() ) {
1292 if ( dti.dta[cat].d[i].lockStat ) 1337 if ( dti.dta[cat].d[i].lockStat )
1293 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ": " + i18n("LOCKED") +"</b><br>" ; 1338 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ": " + i18n("LOCKED") +"</b><br>" ;
1294 else 1339 else
1295 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ":</b> " + tempval+"<br>" ; 1340 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ":</b> " + tempval+"<br>" ;
1296 } 1341 }
1297 tempval = QString (dti.dta[cat].d[i].url.c_str()); 1342 tempval = QString (dti.dta[cat].d[i].url.c_str());
1298 if ( !tempval.isEmpty() ) { 1343 if ( !tempval.isEmpty() ) {
1299 retval += "<b>" +i18n("URL:")+ "</b> " + tempval+"<br>" ; 1344 retval += "<b>" +i18n("URL:")+ "</b> " + tempval+"<br>" ;
1300 } 1345 }
1301 tempval = QString (dti.dta[cat].d[i].launcher.c_str()); 1346 tempval = QString (dti.dta[cat].d[i].launcher.c_str());
1302 if ( !tempval.isEmpty() ) { 1347 if ( !tempval.isEmpty() ) {
1303 retval += "<b>" +i18n("Launcher:")+ "</b> " + tempval+"<br>" ; 1348 retval += "<b>" +i18n("Launcher:")+ "</b> " + tempval+"<br>" ;
1304 } 1349 }
1305 tempval = QString (dti.dta[cat].d[i].comment.c_str()); 1350 tempval = QString (dti.dta[cat].d[i].comment.c_str());
1306 if ( !tempval.isEmpty() ) { 1351 if ( !tempval.isEmpty() ) {
1307 tempval.replace(QRegExp ( "\n" ), "<br>" ); 1352 tempval.replace(QRegExp ( "\n" ), "<br>" );
1308 retval += "<b>" +i18n("Comment:")+ "</b><br>" + tempval+"<br>" ; 1353 retval += "<b>" +i18n("Comment:")+ "</b><br>" + tempval+"<br>" ;
1309 } 1354 }
1310 1355
1311 string ret ( retval.latin1() ); 1356 string ret ( retval.latin1() );
1312 1357
1313 1358
1314 // *foundComment = dti.dta[cat].d[i].comment; 1359 // *foundComment = dti.dta[cat].d[i].comment;
1315 *foundComment = ret; 1360 *foundComment = ret;
1316 return e_normalEntry; 1361 return e_normalEntry;
1317 } 1362 }
1318 } 1363 }
1319 BUG(); 1364 BUG();
1320 return e_generic; 1365 return e_generic;
1321} 1366}
1322 1367
1323bool PwMDoc::compressDta(string *d, char algo) 1368bool PwMDoc::compressDta(string *d, char algo)
1324{ 1369{
1325 PWM_ASSERT(d); 1370 PWM_ASSERT(d);
1326 switch (algo) { 1371 switch (algo) {
1327 case PWM_COMPRESS_GZIP: { 1372 case PWM_COMPRESS_GZIP: {
1328 CompressGzip comp; 1373 CompressGzip comp;
1329 return comp.compress(d); 1374 return comp.compress(d);
1330 } 1375 }
1331#ifndef PWM_EMBEDDED 1376#ifndef PWM_EMBEDDED
1332 case PWM_COMPRESS_BZIP2: { 1377 case PWM_COMPRESS_BZIP2: {
1333 CompressBzip2 comp; 1378 CompressBzip2 comp;
1334 return comp.compress(d); 1379 return comp.compress(d);
1335 } 1380 }
1336#endif 1381#endif
1337 case PWM_COMPRESS_NONE: { 1382 case PWM_COMPRESS_NONE: {
1338 return true; 1383 return true;
1339 } default: { 1384 } default: {
1340 BUG(); 1385 BUG();
1341 } 1386 }
1342 } 1387 }
1343 return false; 1388 return false;
1344} 1389}
1345 1390
1346bool PwMDoc::decompressDta(string *d, char algo) 1391bool PwMDoc::decompressDta(string *d, char algo)
1347{ 1392{
1348 PWM_ASSERT(d); 1393 PWM_ASSERT(d);
1349 switch (algo) { 1394 switch (algo) {
1350 case PWM_COMPRESS_GZIP: { 1395 case PWM_COMPRESS_GZIP: {
1351 CompressGzip comp; 1396 CompressGzip comp;
1352 return comp.decompress(d); 1397 return comp.decompress(d);
1353 } 1398 }
1354#ifndef PWM_EMBEDDED 1399#ifndef PWM_EMBEDDED
1355 case PWM_COMPRESS_BZIP2: { 1400 case PWM_COMPRESS_BZIP2: {
1356 CompressBzip2 comp; 1401 CompressBzip2 comp;
1357 return comp.decompress(d); 1402 return comp.decompress(d);
1358 } 1403 }
1359#endif 1404#endif
1360 case PWM_COMPRESS_NONE: { 1405 case PWM_COMPRESS_NONE: {
1361 return true; 1406 return true;
1362 } 1407 }
1363 } 1408 }
1364 return false; 1409 return false;
1365} 1410}
1366 1411
1367PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo, 1412PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo,
1368 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1413 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1369) 1414)
1370{ 1415{
1371 PWM_ASSERT(d); 1416 PWM_ASSERT(d);
1372 PWM_ASSERT(pw); 1417 PWM_ASSERT(pw);
1373 PWM_ASSERT(f); 1418 PWM_ASSERT(f);
1374 1419
1375 size_t encSize; 1420 size_t encSize;
1376 byte *encrypted = 0; 1421 byte *encrypted = 0;
1377 1422
1378 switch (algo) { 1423 switch (algo) {
1379 case PWM_CRYPT_BLOWFISH: { 1424 case PWM_CRYPT_BLOWFISH: {
1380 Blowfish::padNull(d); 1425 Blowfish::padNull(d);
1381 encSize = d->length(); 1426 encSize = d->length();
1382 encrypted = new byte[encSize]; 1427 encrypted = new byte[encSize];
1383 Blowfish bf; 1428 Blowfish bf;
1384 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1429 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1385 delete [] encrypted; 1430 delete [] encrypted;
1386 return e_weakPw; 1431 return e_weakPw;
1387 } 1432 }
1388 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1433 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1389 break; 1434 break;
1390 } 1435 }
1391 case PWM_CRYPT_AES128: 1436 case PWM_CRYPT_AES128:
1392 /*... fall through */ 1437 /*... fall through */
1393 case PWM_CRYPT_AES192: 1438 case PWM_CRYPT_AES192:
1394 case PWM_CRYPT_AES256: 1439 case PWM_CRYPT_AES256:
1395 case PWM_CRYPT_3DES: 1440 case PWM_CRYPT_3DES:
1396 case PWM_CRYPT_TWOFISH: 1441 case PWM_CRYPT_TWOFISH:
1397 case PWM_CRYPT_TWOFISH128: { 1442 case PWM_CRYPT_TWOFISH128: {
1398 if (!LibGCryptIf::available()) 1443 if (!LibGCryptIf::available())
1399 return e_cryptNotImpl; 1444 return e_cryptNotImpl;
1400 LibGCryptIf gc; 1445 LibGCryptIf gc;
1401 PwMerror err; 1446 PwMerror err;
1402 unsigned char *plain = new unsigned char[d->length() + 1024]; 1447 unsigned char *plain = new unsigned char[d->length() + 1024];
1403 memcpy(plain, d->c_str(), d->length()); 1448 memcpy(plain, d->c_str(), d->length());
1404 err = gc.encrypt(&encrypted, 1449 err = gc.encrypt(&encrypted,
1405 &encSize, 1450 &encSize,
1406 plain, 1451 plain,
1407 d->length(), 1452 d->length(),
1408 reinterpret_cast<const unsigned char *>(pw->latin1()), 1453 reinterpret_cast<const unsigned char *>(pw->latin1()),
1409 pw->length(), 1454 pw->length(),
1410 algo, 1455 algo,
1411 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1456 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1412 ); 1457 );
1413 delete [] plain; 1458 delete [] plain;
1414 if (err != e_success) 1459 if (err != e_success)
1415 return e_cryptNotImpl; 1460 return e_cryptNotImpl;
1416 break; 1461 break;
1417 } 1462 }
1418 default: { 1463 default: {
1419 delete_ifnot_null_array(encrypted); 1464 delete_ifnot_null_array(encrypted);
1420 return e_cryptNotImpl; 1465 return e_cryptNotImpl;
1421 } } 1466 } }
1422 1467
1423 // write encrypted data to file 1468 // write encrypted data to file
1424 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1469 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1425 static_cast<Q_ULONG>(encSize)) 1470 static_cast<Q_ULONG>(encSize))
1426 != static_cast<Q_LONG>(encSize)) { 1471 != static_cast<Q_LONG>(encSize)) {
1427 delete_ifnot_null_array(encrypted); 1472 delete_ifnot_null_array(encrypted);
1428 return e_writeFile; 1473 return e_writeFile;
1429 } 1474 }
1430 delete_ifnot_null_array(encrypted); 1475 delete_ifnot_null_array(encrypted);
1431 return e_success; 1476 return e_success;
1432} 1477}
1433 1478
1434PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1479PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1435 char algo, 1480 char algo,
1436 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase 1481 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
1437 QFile *f) 1482 QFile *f)
1438{ 1483{
1439 PWM_ASSERT(d); 1484 PWM_ASSERT(d);
1440 PWM_ASSERT(pw); 1485 PWM_ASSERT(pw);
1441 PWM_ASSERT(f); 1486 PWM_ASSERT(f);
1442 1487
1443 unsigned int cryptLen = f->size() - pos; 1488 unsigned int cryptLen = f->size() - pos;
1444 byte *encrypted = new byte[cryptLen]; 1489 byte *encrypted = new byte[cryptLen];
1445 byte *decrypted = new byte[cryptLen]; 1490 byte *decrypted = new byte[cryptLen];
1446 1491
1447 f->at(pos); 1492 f->at(pos);
1448#ifndef PWM_EMBEDDED 1493#ifndef PWM_EMBEDDED
1449 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1494 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1450 static_cast<Q_ULONG>(cryptLen)) 1495 static_cast<Q_ULONG>(cryptLen))
1451 != static_cast<Q_LONG>(cryptLen)) { 1496 != static_cast<Q_LONG>(cryptLen)) {
1452 delete [] encrypted; 1497 delete [] encrypted;
1453 delete [] decrypted; 1498 delete [] decrypted;
1454 return e_readFile; 1499 return e_readFile;
1455 } 1500 }
1456#else 1501#else
1457 if (f->readBlock((char *)(encrypted), 1502 if (f->readBlock((char *)(encrypted),
1458 (unsigned long)(cryptLen)) 1503 (unsigned long)(cryptLen))
1459 != (long)(cryptLen)) { 1504 != (long)(cryptLen)) {
1460 delete [] encrypted; 1505 delete [] encrypted;
1461 delete [] decrypted; 1506 delete [] decrypted;
1462 return e_readFile; 1507 return e_readFile;
1463 } 1508 }
1464#endif 1509#endif
1465 switch (algo) { 1510 switch (algo) {
1466 case PWM_CRYPT_BLOWFISH: { 1511 case PWM_CRYPT_BLOWFISH: {
1467 Blowfish bf; 1512 Blowfish bf;
1468 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1513 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1469 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1514 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1470 break; 1515 break;
1471 } 1516 }
1472 case PWM_CRYPT_AES128: 1517 case PWM_CRYPT_AES128:
1473 /*... fall through */ 1518 /*... fall through */
1474 case PWM_CRYPT_AES192: 1519 case PWM_CRYPT_AES192:
1475 case PWM_CRYPT_AES256: 1520 case PWM_CRYPT_AES256:
1476 case PWM_CRYPT_3DES: 1521 case PWM_CRYPT_3DES:
1477 case PWM_CRYPT_TWOFISH: 1522 case PWM_CRYPT_TWOFISH:
1478 case PWM_CRYPT_TWOFISH128: { 1523 case PWM_CRYPT_TWOFISH128: {
1479 if (!LibGCryptIf::available()) 1524 if (!LibGCryptIf::available())
1480 return e_cryptNotImpl; 1525 return e_cryptNotImpl;
1481 LibGCryptIf gc; 1526 LibGCryptIf gc;
1482 PwMerror err; 1527 PwMerror err;
1483 err = gc.decrypt(&decrypted, 1528 err = gc.decrypt(&decrypted,
1484 &cryptLen, 1529 &cryptLen,
1485 encrypted, 1530 encrypted,
1486 cryptLen, 1531 cryptLen,
1487 reinterpret_cast<const unsigned char *>(pw->latin1()), 1532 reinterpret_cast<const unsigned char *>(pw->latin1()),
1488 pw->length(), 1533 pw->length(),
1489 algo, 1534 algo,
1490 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1535 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1491); 1536);
1492 if (err != e_success) { 1537 if (err != e_success) {
1493 delete [] encrypted; 1538 delete [] encrypted;
1494 delete [] decrypted; 1539 delete [] decrypted;
1495 return e_cryptNotImpl; 1540 return e_cryptNotImpl;
1496 } 1541 }
1497 break; 1542 break;
1498 } 1543 }
1499 default: { 1544 default: {
1500 delete [] encrypted; 1545 delete [] encrypted;
1501 delete [] decrypted; 1546 delete [] decrypted;
1502 return e_cryptNotImpl; 1547 return e_cryptNotImpl;
1503 } } 1548 } }
1504 delete [] encrypted; 1549 delete [] encrypted;
1505#ifndef PWM_EMBEDDED 1550#ifndef PWM_EMBEDDED
1506 d->assign(reinterpret_cast<const char *>(decrypted), 1551 d->assign(reinterpret_cast<const char *>(decrypted),
1507 static_cast<string::size_type>(cryptLen)); 1552 static_cast<string::size_type>(cryptLen));
1508#else 1553#else
1509 d->assign((const char *)(decrypted), 1554 d->assign((const char *)(decrypted),
1510 (string::size_type)(cryptLen)); 1555 (string::size_type)(cryptLen));
1511#endif 1556#endif
1512 delete [] decrypted; 1557 delete [] decrypted;
1513 if (algo == PWM_CRYPT_BLOWFISH) { 1558 if (algo == PWM_CRYPT_BLOWFISH) {
1514 if (!Blowfish::unpadNull(d)) { 1559 if (!Blowfish::unpadNull(d)) {
1515 BUG(); 1560 BUG();
1516 return e_readFile; 1561 return e_readFile;
1517 } 1562 }
1518 } 1563 }
1519 return e_success; 1564 return e_success;
1520} 1565}
1521 1566
1522PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1567PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1523 const string *dataStream) 1568 const string *dataStream)
1524{ 1569{
1525 PWM_ASSERT(dataHash); 1570 PWM_ASSERT(dataHash);
1526 PWM_ASSERT(dataStream); 1571 PWM_ASSERT(dataStream);
1527 switch(dataHashType) { 1572 switch(dataHashType) {
1528 case PWM_HASH_SHA1: { 1573 case PWM_HASH_SHA1: {
1529 Sha1 hash; 1574 Sha1 hash;
1530 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); 1575 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
1531 string ret = hash.sha1_read(); 1576 string ret = hash.sha1_read();
1532 if (ret != *dataHash) 1577 if (ret != *dataHash)
1533 return e_fileCorrupt; 1578 return e_fileCorrupt;
1534 break; 1579 break;
1535 } 1580 }
1536 case PWM_HASH_SHA256: 1581 case PWM_HASH_SHA256:
1537 /*... fall through */ 1582 /*... fall through */
1538 case PWM_HASH_SHA384: 1583 case PWM_HASH_SHA384:
1539 case PWM_HASH_SHA512: 1584 case PWM_HASH_SHA512:
1540 case PWM_HASH_MD5: 1585 case PWM_HASH_MD5:
1541 case PWM_HASH_RMD160: 1586 case PWM_HASH_RMD160:
1542 case PWM_HASH_TIGER: { 1587 case PWM_HASH_TIGER: {
1543 if (!LibGCryptIf::available()) 1588 if (!LibGCryptIf::available())
1544 return e_hashNotImpl; 1589 return e_hashNotImpl;
1545 LibGCryptIf gc; 1590 LibGCryptIf gc;
1546 PwMerror err; 1591 PwMerror err;
1547 unsigned char *buf; 1592 unsigned char *buf;
1548 size_t hashLen; 1593 size_t hashLen;
1549 err = gc.hash(&buf, 1594 err = gc.hash(&buf,
1550 &hashLen, 1595 &hashLen,
1551 reinterpret_cast<const unsigned char *>(dataStream->c_str()), 1596 reinterpret_cast<const unsigned char *>(dataStream->c_str()),
1552 dataStream->length(), 1597 dataStream->length(),
1553 dataHashType); 1598 dataHashType);
1554 if (err != e_success) 1599 if (err != e_success)
1555 return e_hashNotImpl; 1600 return e_hashNotImpl;
1556 string calcHash(reinterpret_cast<const char *>(buf), 1601 string calcHash(reinterpret_cast<const char *>(buf),
1557 static_cast<string::size_type>(hashLen)); 1602 static_cast<string::size_type>(hashLen));
1558 delete [] buf; 1603 delete [] buf;
1559 if (calcHash != *dataHash) 1604 if (calcHash != *dataHash)
1560 return e_fileCorrupt; 1605 return e_fileCorrupt;
1561 break; 1606 break;
1562 } 1607 }
1563 default: 1608 default:
1564 return e_hashNotImpl; 1609 return e_hashNotImpl;
1565 } 1610 }
1566 return e_success; 1611 return e_success;
1567} 1612}
1568 1613
1569bool PwMDoc::lockAt(unsigned int category, unsigned int index, 1614bool PwMDoc::lockAt(unsigned int category, unsigned int index,
1570 bool lock) 1615 bool lock)
1571{ 1616{
1572 if (index >= numEntries(category)) { 1617 if (index >= numEntries(category)) {
1573 BUG(); 1618 BUG();
1574 return false; 1619 return false;
1575 } 1620 }
1576 if (lock == dti.dta[category].d[index].lockStat) 1621 if (lock == dti.dta[category].d[index].lockStat)
1577 return true; 1622 return true;
1578 1623
1579 if (!lock && currentPw != "") { 1624 if (!lock && currentPw != "") {
1580 // "unlocking" and "password is already set" 1625 // "unlocking" and "password is already set"
1581 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1626 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1582 // unlocking without pw not allowed 1627 // unlocking without pw not allowed
1583 QString pw; 1628 QString pw;
1584 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1629 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1585 if (pw != "") { 1630 if (pw != "") {
1586 if (pw != currentPw) { 1631 if (pw != currentPw) {
1587 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1632 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1588 return false; 1633 return false;
1589 } else { 1634 } else {
1590 timer()->start(DocTimer::id_mpwTimer); 1635 timer()->start(DocTimer::id_mpwTimer);
1591 } 1636 }
1592 } else { 1637 } else {
1593 return false; 1638 return false;
1594 } 1639 }
1595 } else { 1640 } else {
1596 timer()->start(DocTimer::id_mpwTimer); 1641 timer()->start(DocTimer::id_mpwTimer);
1597 } 1642 }
1598 } 1643 }
1599 1644
1600 dti.dta[category].d[index].lockStat = lock; 1645 dti.dta[category].d[index].lockStat = lock;
1601 dti.dta[category].d[index].rev++; // increment revision counter. 1646 dti.dta[category].d[index].rev++; // increment revision counter.
1602 1647
1603 emitDataChanged(this); 1648 emitDataChanged(this);
1604 if (!lock) 1649 if (!lock)
1605 timer()->start(DocTimer::id_autoLockTimer); 1650 timer()->start(DocTimer::id_autoLockTimer);
1606 1651
1607 return true; 1652 return true;
1608 1653
1609} 1654}
1610 1655
1611bool PwMDoc::lockAt(const QString &category,unsigned int index, 1656bool PwMDoc::lockAt(const QString &category,unsigned int index,
1612 bool lock) 1657 bool lock)
1613{ 1658{
1614 unsigned int cat = 0; 1659 unsigned int cat = 0;
1615 1660
1616 if (!findCategory(category, &cat)) { 1661 if (!findCategory(category, &cat)) {
1617 BUG(); 1662 BUG();
1618 return false; 1663 return false;
1619 } 1664 }
1620 1665
1621 return lockAt(cat, index, lock); 1666 return lockAt(cat, index, lock);
1622} 1667}
1623 1668
1624bool PwMDoc::lockAll(bool lock) 1669bool PwMDoc::lockAll(bool lock)
1625{ 1670{
1626 if (!lock && isDeepLocked()) { 1671 if (!lock && isDeepLocked()) {
1627 PwMerror ret; 1672 PwMerror ret;
1628 ret = deepLock(false); 1673 ret = deepLock(false);
1629 if (ret != e_success) 1674 if (ret != e_success)
1630 return false; 1675 return false;
1631 return true; 1676 return true;
1632 } 1677 }
1633 if (isDocEmpty()) { 1678 if (isDocEmpty()) {
1634 return true; 1679 return true;
1635 } 1680 }
1636 if (!lock && currentPw != "") { 1681 if (!lock && currentPw != "") {
1637 // unlocking and password is already set 1682 // unlocking and password is already set
1638 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1683 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1639 // unlocking without pw not allowed 1684 // unlocking without pw not allowed
1640 QString pw; 1685 QString pw;
1641 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1686 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1642 if (pw != "") { 1687 if (pw != "") {
1643 if (pw != currentPw) { 1688 if (pw != currentPw) {
1644 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1689 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1645 return false; 1690 return false;
1646 } else { 1691 } else {
1647 timer()->start(DocTimer::id_mpwTimer); 1692 timer()->start(DocTimer::id_mpwTimer);
1648 } 1693 }
1649 } else { 1694 } else {
1650 return false; 1695 return false;
1651 } 1696 }
1652 } else { 1697 } else {
1653 timer()->start(DocTimer::id_mpwTimer); 1698 timer()->start(DocTimer::id_mpwTimer);
1654 } 1699 }
1655 } 1700 }
1656 1701
1657 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1702 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1658 catEnd = dti.dta.end(), 1703 catEnd = dti.dta.end(),
1659 catI = catBegin; 1704 catI = catBegin;
1660 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1705 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1661 while (catI != catEnd) { 1706 while (catI != catEnd) {
1662 entrBegin = catI->d.begin(); 1707 entrBegin = catI->d.begin();
1663 entrEnd = catI->d.end(); 1708 entrEnd = catI->d.end();
1664 entrI = entrBegin; 1709 entrI = entrBegin;
1665 while (entrI != entrEnd) { 1710 while (entrI != entrEnd) {
1666 entrI->lockStat = lock; 1711 entrI->lockStat = lock;
1667 entrI->rev++; // increment revision counter. 1712 entrI->rev++; // increment revision counter.
1668 ++entrI; 1713 ++entrI;
1669 } 1714 }
1670 ++catI; 1715 ++catI;
1671 } 1716 }
1672 1717
1673 emitDataChanged(this); 1718 emitDataChanged(this);
1674 if (lock) 1719 if (lock)
1675 timer()->stop(DocTimer::id_autoLockTimer); 1720 timer()->stop(DocTimer::id_autoLockTimer);
1676 else 1721 else
1677 timer()->start(DocTimer::id_autoLockTimer); 1722 timer()->start(DocTimer::id_autoLockTimer);
1678 1723
1679 return true; 1724 return true;
1680} 1725}
1681 1726
1682bool PwMDoc::isLocked(const QString &category, unsigned int index) 1727bool PwMDoc::isLocked(const QString &category, unsigned int index)
1683{ 1728{
1684 unsigned int cat = 0; 1729 unsigned int cat = 0;
1685 1730
1686 if (!findCategory(category, &cat)) { 1731 if (!findCategory(category, &cat)) {
1687 BUG(); 1732 BUG();
1688 return false; 1733 return false;
1689 } 1734 }
1690 1735
1691 return isLocked(cat, index); 1736 return isLocked(cat, index);
1692} 1737}
1693 1738
1694bool PwMDoc::unlockAll_tempoary(bool revert) 1739bool PwMDoc::unlockAll_tempoary(bool revert)
1695{ 1740{
1696 static vector< vector<bool> > *oldLockStates = 0; 1741 static vector< vector<bool> > *oldLockStates = 0;
1697 static bool wasDeepLocked; 1742 static bool wasDeepLocked;
1698 1743
1699 if (revert) {// revert the unlocking 1744 if (revert) {// revert the unlocking
1700 if (oldLockStates) { 1745 if (oldLockStates) {
1701 /* we actually _have_ unlocked something, because 1746 /* we actually _have_ unlocked something, because
1702 * we have allocated space for the oldLockStates. 1747 * we have allocated space for the oldLockStates.
1703 * So, go on and revert them! 1748 * So, go on and revert them!
1704 */ 1749 */
1705 if (wasDeepLocked) { 1750 if (wasDeepLocked) {
1706 PwMerror ret = deepLock(true); 1751 PwMerror ret = deepLock(true);
1707 if (ret == e_success) { 1752 if (ret == e_success) {
1708 /* deep-lock succeed. We are save. 1753 /* deep-lock succeed. We are save.
1709 * (but if it failed, just go on 1754 * (but if it failed, just go on
1710 * lock them normally) 1755 * lock them normally)
1711 */ 1756 */
1712 delete_and_null(oldLockStates); 1757 delete_and_null(oldLockStates);
1713 timer()->start(DocTimer::id_autoLockTimer); 1758 timer()->start(DocTimer::id_autoLockTimer);
1714 printDebug("tempoary unlocking of dta " 1759 printDebug("tempoary unlocking of dta "
1715 "reverted by deep-locking."); 1760 "reverted by deep-locking.");
1716 return true; 1761 return true;
1717 } 1762 }
1718 printDebug("deep-lock failed while reverting! " 1763 printDebug("deep-lock failed while reverting! "
1719 "Falling back to normal-lock."); 1764 "Falling back to normal-lock.");
1720 } 1765 }
1721 if (unlikely(!wasDeepLocked && 1766 if (unlikely(!wasDeepLocked &&
1722 numCategories() != oldLockStates->size())) { 1767 numCategories() != oldLockStates->size())) {
1723 /* DOH! We have modified "dta" while 1768 /* DOH! We have modified "dta" while
1724 * it was unlocked tempoary. DON'T DO THIS! 1769 * it was unlocked tempoary. DON'T DO THIS!
1725 */ 1770 */
1726 BUG(); 1771 BUG();
1727 delete_and_null(oldLockStates); 1772 delete_and_null(oldLockStates);
1728 timer()->start(DocTimer::id_autoLockTimer); 1773 timer()->start(DocTimer::id_autoLockTimer);
1729 return false; 1774 return false;
1730 } 1775 }
1731 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1776 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1732 catEnd = dti.dta.end(), 1777 catEnd = dti.dta.end(),
1733 catI = catBegin; 1778 catI = catBegin;
1734 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1779 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1735 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); 1780 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin();
1736 vector<bool>::iterator oldEntrStatBegin, 1781 vector<bool>::iterator oldEntrStatBegin,
1737 oldEntrStatEnd, 1782 oldEntrStatEnd,
1738 oldEntrStatI; 1783 oldEntrStatI;
1739 while (catI != catEnd) { 1784 while (catI != catEnd) {
1740 entrBegin = catI->d.begin(); 1785 entrBegin = catI->d.begin();
1741 entrEnd = catI->d.end(); 1786 entrEnd = catI->d.end();
1742 entrI = entrBegin; 1787 entrI = entrBegin;
1743 if (likely(!wasDeepLocked)) { 1788 if (likely(!wasDeepLocked)) {
1744 oldEntrStatBegin = oldCatStatI->begin(); 1789 oldEntrStatBegin = oldCatStatI->begin();
1745 oldEntrStatEnd = oldCatStatI->end(); 1790 oldEntrStatEnd = oldCatStatI->end();
1746 oldEntrStatI = oldEntrStatBegin; 1791 oldEntrStatI = oldEntrStatBegin;
1747 if (unlikely(catI->d.size() != oldCatStatI->size())) { 1792 if (unlikely(catI->d.size() != oldCatStatI->size())) {
1748 /* DOH! We have modified "dta" while 1793 /* DOH! We have modified "dta" while
1749 * it was unlocked tempoary. DON'T DO THIS! 1794 * it was unlocked tempoary. DON'T DO THIS!
1750 */ 1795 */
1751 BUG(); 1796 BUG();
1752 delete_and_null(oldLockStates); 1797 delete_and_null(oldLockStates);
1753 timer()->start(DocTimer::id_autoLockTimer); 1798 timer()->start(DocTimer::id_autoLockTimer);
1754 return false; 1799 return false;
1755 } 1800 }
1756 } 1801 }
1757 while (entrI != entrEnd) { 1802 while (entrI != entrEnd) {
1758 if (wasDeepLocked) { 1803 if (wasDeepLocked) {
1759 /* this is an error-fallback if 1804 /* this is an error-fallback if
1760 * deeplock didn't succeed 1805 * deeplock didn't succeed
1761 */ 1806 */
1762 entrI->lockStat = true; 1807 entrI->lockStat = true;
1763 } else { 1808 } else {
1764 entrI->lockStat = *oldEntrStatI; 1809 entrI->lockStat = *oldEntrStatI;
1765 } 1810 }
1766 ++entrI; 1811 ++entrI;
1767 if (likely(!wasDeepLocked)) 1812 if (likely(!wasDeepLocked))
1768 ++oldEntrStatI; 1813 ++oldEntrStatI;
1769 } 1814 }
1770 ++catI; 1815 ++catI;
1771 if (likely(!wasDeepLocked)) 1816 if (likely(!wasDeepLocked))
1772 ++oldCatStatI; 1817 ++oldCatStatI;
1773 } 1818 }
1774 delete_and_null(oldLockStates); 1819 delete_and_null(oldLockStates);
1775 if (unlikely(wasDeepLocked)) { 1820 if (unlikely(wasDeepLocked)) {
1776 /* error fallback... */ 1821 /* error fallback... */
1777 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1822 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1778 emitDataChanged(this); 1823 emitDataChanged(this);
1779 printDebug("WARNING: unlockAll_tempoary(true) " 1824 printDebug("WARNING: unlockAll_tempoary(true) "
1780 "deeplock fallback!"); 1825 "deeplock fallback!");
1781 } 1826 }
1782 printDebug("tempoary unlocking of dta reverted."); 1827 printDebug("tempoary unlocking of dta reverted.");
1783 } else { 1828 } else {
1784 printDebug("unlockAll_tempoary(true): nothing to do."); 1829 printDebug("unlockAll_tempoary(true): nothing to do.");
1785 } 1830 }
1786 timer()->start(DocTimer::id_autoLockTimer); 1831 timer()->start(DocTimer::id_autoLockTimer);
1787 } else {// unlock all data tempoary 1832 } else {// unlock all data tempoary
1788 if (unlikely(oldLockStates != 0)) { 1833 if (unlikely(oldLockStates != 0)) {
1789 /* DOH! We have already unlocked the data tempoarly. 1834 /* DOH! We have already unlocked the data tempoarly.
1790 * No need to do it twice. ;) 1835 * No need to do it twice. ;)
1791 */ 1836 */
1792 BUG(); 1837 BUG();
1793 return false; 1838 return false;
1794 } 1839 }
1795 wasDeepLocked = false; 1840 wasDeepLocked = false;
1796 bool mustUnlock = false; 1841 bool mustUnlock = false;
1797 if (isDeepLocked()) { 1842 if (isDeepLocked()) {
1798 PwMerror ret; 1843 PwMerror ret;
1799 while (1) { 1844 while (1) {
1800 ret = deepLock(false); 1845 ret = deepLock(false);
1801 if (ret == e_success) { 1846 if (ret == e_success) {
1802 break; 1847 break;
1803 } else if (ret == e_wrongPw) { 1848 } else if (ret == e_wrongPw) {
1804 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1849 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1805 } else { 1850 } else {
1806 printDebug("deep-unlocking failed while " 1851 printDebug("deep-unlocking failed while "
1807 "tempoary unlocking!"); 1852 "tempoary unlocking!");
1808 return false; 1853 return false;
1809 } 1854 }
1810 } 1855 }
1811 wasDeepLocked = true; 1856 wasDeepLocked = true;
1812 mustUnlock = true; 1857 mustUnlock = true;
1813 } else { 1858 } else {
1814 // first check if it's needed to unlock some entries 1859 // first check if it's needed to unlock some entries
1815 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1860 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1816 catEnd = dti.dta.end(), 1861 catEnd = dti.dta.end(),
1817 catI = catBegin; 1862 catI = catBegin;
1818 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1863 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1819 while (catI != catEnd) { 1864 while (catI != catEnd) {
1820 entrBegin = catI->d.begin(); 1865 entrBegin = catI->d.begin();
1821 entrEnd = catI->d.end(); 1866 entrEnd = catI->d.end();
1822 entrI = entrBegin; 1867 entrI = entrBegin;
1823 while (entrI != entrEnd) { 1868 while (entrI != entrEnd) {
1824 if (entrI->lockStat == true) { 1869 if (entrI->lockStat == true) {
1825 mustUnlock = true; 1870 mustUnlock = true;
1826 break; 1871 break;
1827 } 1872 }
1828 ++entrI; 1873 ++entrI;
1829 } 1874 }
1830 if (mustUnlock) 1875 if (mustUnlock)
1831 break; 1876 break;
1832 ++catI; 1877 ++catI;
1833 } 1878 }
1834 } 1879 }
1835 if (!mustUnlock) { 1880 if (!mustUnlock) {
1836 // nothing to do. 1881 // nothing to do.
1837 timer()->stop(DocTimer::id_autoLockTimer); 1882 timer()->stop(DocTimer::id_autoLockTimer);
1838 printDebug("unlockAll_tempoary(): nothing to do."); 1883 printDebug("unlockAll_tempoary(): nothing to do.");
1839 return true; 1884 return true;
1840 } else if (!wasDeepLocked) { 1885 } else if (!wasDeepLocked) {
1841 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && 1886 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) &&
1842 currentPw != "") { 1887 currentPw != "") {
1843 /* we can't unlock without mpw, so 1888 /* we can't unlock without mpw, so
1844 * we need to ask for it. 1889 * we need to ask for it.
1845 */ 1890 */
1846 QString pw; 1891 QString pw;
1847 while (1) { 1892 while (1) {
1848 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1893 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1849 if (pw == "") { 1894 if (pw == "") {
1850 return false; 1895 return false;
1851 } else if (pw == currentPw) { 1896 } else if (pw == currentPw) {
1852 break; 1897 break;
1853 } 1898 }
1854 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1899 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1855 } 1900 }
1856 } 1901 }
1857 } 1902 }
1858 timer()->stop(DocTimer::id_autoLockTimer); 1903 timer()->stop(DocTimer::id_autoLockTimer);
1859 oldLockStates = new vector< vector<bool> >; 1904 oldLockStates = new vector< vector<bool> >;
1860 vector<bool> tmp_vec; 1905 vector<bool> tmp_vec;
1861 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1906 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1862 catEnd = dti.dta.end(), 1907 catEnd = dti.dta.end(),
1863 catI = catBegin; 1908 catI = catBegin;
1864 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1909 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1865 while (catI != catEnd) { 1910 while (catI != catEnd) {
1866 entrBegin = catI->d.begin(); 1911 entrBegin = catI->d.begin();
1867 entrEnd = catI->d.end(); 1912 entrEnd = catI->d.end();
1868 entrI = entrBegin; 1913 entrI = entrBegin;
1869 while (entrI != entrEnd) { 1914 while (entrI != entrEnd) {
1870 if (!wasDeepLocked) { 1915 if (!wasDeepLocked) {
1871 tmp_vec.push_back(entrI->lockStat); 1916 tmp_vec.push_back(entrI->lockStat);
1872 } 1917 }
1873 entrI->lockStat = false; 1918 entrI->lockStat = false;
1874 ++entrI; 1919 ++entrI;
1875 } 1920 }
1876 if (!wasDeepLocked) { 1921 if (!wasDeepLocked) {
1877 oldLockStates->push_back(tmp_vec); 1922 oldLockStates->push_back(tmp_vec);
1878 tmp_vec.clear(); 1923 tmp_vec.clear();
1879 } 1924 }
1880 ++catI; 1925 ++catI;
1881 } 1926 }
1882 printDebug("tempoary unlocked dta."); 1927 printDebug("tempoary unlocked dta.");
1883 } 1928 }
1884 1929
1885 return true; 1930 return true;
1886} 1931}
1887 1932
1888PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) 1933PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
1889{ 1934{
1890 PwMerror ret; 1935 PwMerror ret;
1891 /* NOTE: saveDoc() depends on this function to return 1936 /* NOTE: saveDoc() depends on this function to return
1892 * e_success if saveToFile == false 1937 * e_success if saveToFile == false
1893 */ 1938 */
1894 1939
1895 if (lock) { 1940 if (lock) {
1896 if (isDeepLocked()) 1941 if (isDeepLocked())
1897 return e_lock; 1942 return e_lock;
1898 if (saveToFile) { 1943 if (saveToFile) {
1899 if (isDocEmpty()) 1944 if (isDocEmpty())
1900 return e_docIsEmpty; 1945 return e_docIsEmpty;
1901 ret = saveDoc(conf()->confGlobCompression()); 1946 ret = saveDoc(conf()->confGlobCompression());
1902 if (ret == e_filename) { 1947 if (ret == e_filename) {
1903 /* the doc wasn't saved to a file 1948 /* the doc wasn't saved to a file
1904 * by the user, yet. 1949 * by the user, yet.
1905 */ 1950 */
1906 cantDeeplock_notSavedMsgBox(); 1951 cantDeeplock_notSavedMsgBox();
1907 return e_docNotSaved; 1952 return e_docNotSaved;
1908 } else if (ret != e_success) { 1953 } else if (ret != e_success) {
1909 return e_lock; 1954 return e_lock;
1910 } 1955 }
1911 } 1956 }
1912 timer()->stop(DocTimer::id_autoLockTimer); 1957 timer()->stop(DocTimer::id_autoLockTimer);
1913 clearDoc(); 1958 clearDoc();
1914 PwMDataItem d; 1959 PwMDataItem d;
1915 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); 1960 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
1916 d.comment = IS_DEEPLOCKED_MSG.latin1(); 1961 d.comment = IS_DEEPLOCKED_MSG.latin1();
1917 d.listViewPos = 0; 1962 d.listViewPos = 0;
1918 addEntry(DEFAULT_CATEGORY, &d, true); 1963 addEntry(DEFAULT_CATEGORY, &d, true);
1919 lockAt(DEFAULT_CATEGORY, 0, true); 1964 lockAt(DEFAULT_CATEGORY, 0, true);
1920 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 1965 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
1921 setDocStatFlag(DOC_STAT_DEEPLOCKED); 1966 setDocStatFlag(DOC_STAT_DEEPLOCKED);
1922 } else { 1967 } else {
1923 if (!isDeepLocked()) 1968 if (!isDeepLocked())
1924 return e_lock; 1969 return e_lock;
1925 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) 1970 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
1926 ? 0 : 1); 1971 ? 0 : 1);
1927 if (ret == e_wrongPw) { 1972 if (ret == e_wrongPw) {
1928 return e_wrongPw; 1973 return e_wrongPw;
1929 } else if (ret != e_success) { 1974 } else if (ret != e_success) {
1930 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") 1975 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
1931 + tostr(static_cast<int>(ret))); 1976 + tostr(static_cast<int>(ret)));
1932 return e_lock; 1977 return e_lock;
1933 } 1978 }
1934 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1979 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1935 timer()->start(DocTimer::id_autoLockTimer); 1980 timer()->start(DocTimer::id_autoLockTimer);
1936 } 1981 }
1937 1982
1938 emitDataChanged(this); 1983 emitDataChanged(this);
1939 return e_success; 1984 return e_success;
1940} 1985}
1941 1986
1942void PwMDoc::_deepUnlock() 1987void PwMDoc::_deepUnlock()
1943{ 1988{
1944 deepLock(false); 1989 deepLock(false);
1945} 1990}
1946 1991
1947void PwMDoc::clearDoc() 1992void PwMDoc::clearDoc()
1948{ 1993{
1949 dti.clear(); 1994 dti.clear();
1950 PwMCategoryItem d; 1995 PwMCategoryItem d;
1951 //US ENH: to initialize all members with meaningfull data. 1996 //US ENH: to initialize all members with meaningfull data.
1952 d.clear(); 1997 d.clear();
1953 d.name = DEFAULT_CATEGORY.latin1(); 1998 d.name = DEFAULT_CATEGORY.latin1();
1954 dti.dta.push_back(d); 1999 dti.dta.push_back(d);
1955 currentPw = ""; 2000 currentPw = "";
1956 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 2001 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
1957} 2002}
1958 2003
1959void PwMDoc::changeCurrentPw() 2004void PwMDoc::changeCurrentPw()
1960{ 2005{
1961 if (currentPw == "") 2006 if (currentPw == "")
1962 return; // doc hasn't been saved. No mpw available. 2007 return; // doc hasn't been saved. No mpw available.
1963 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 2008 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
1964 QString pw = requestMpwChange(&currentPw, &useChipcard); 2009 QString pw = requestMpwChange(&currentPw, &useChipcard);
1965 if (pw == "") 2010 if (pw == "")