-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 65 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.h | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdocui.cpp | 12 |
3 files changed, 67 insertions, 12 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp index e9906a4..f4a1636 100644 --- a/pwmanager/pwmanager/pwmdoc.cpp +++ b/pwmanager/pwmanager/pwmdoc.cpp | |||
@@ -1,992 +1,1034 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * * | 2 | * * |
3 | * copyright (C) 2003, 2004 by Michael Buesch * | 3 | * copyright (C) 2003, 2004 by Michael Buesch * |
4 | * email: mbuesch@freenet.de * | 4 | * email: mbuesch@freenet.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License version 2 * | 7 | * it under the terms of the GNU General Public License version 2 * |
8 | * as published by the Free Software Foundation. * | 8 | * as published by the Free Software Foundation. * |
9 | * * | 9 | * * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | /*************************************************************************** | 12 | /*************************************************************************** |
13 | * copyright (C) 2004 by Ulf Schenk | 13 | * copyright (C) 2004 by Ulf Schenk |
14 | * This file is originaly based on version 2.0 of pwmanager | 14 | * This file is originaly based on version 1.1 of pwmanager |
15 | * and was modified to run on embedded devices that run microkde | 15 | * and was modified to run on embedded devices that run microkde |
16 | * | 16 | * |
17 | * $Id$ | 17 | * $Id$ |
18 | **************************************************************************/ | 18 | **************************************************************************/ |
19 | 19 | ||
20 | #include "pwmdoc.h" | 20 | #include "pwmdoc.h" |
21 | #include "pwmview.h" | 21 | #include "pwmview.h" |
22 | #include "blowfish.h" | 22 | #include "blowfish.h" |
23 | #include "sha1.h" | 23 | #include "sha1.h" |
24 | #include "globalstuff.h" | 24 | #include "globalstuff.h" |
25 | #include "gpasmanfile.h" | 25 | #include "gpasmanfile.h" |
26 | #include "serializer.h" | 26 | #include "serializer.h" |
27 | #include "compressgzip.h" | 27 | #include "compressgzip.h" |
28 | //US#include "compressbzip2.h" | 28 | //US#include "compressbzip2.h" |
29 | #include "randomizer.h" | 29 | #include "randomizer.h" |
30 | #include "pwminit.h" | 30 | #include "pwminit.h" |
31 | #include "libgcryptif.h" | 31 | #include "libgcryptif.h" |
32 | #ifdef PWM_EMBEDDED | 32 | #ifdef PWM_EMBEDDED |
33 | #include "pwmprefs.h" | 33 | #include "pwmprefs.h" |
34 | #include "kglobal.h" | 34 | #include "kglobal.h" |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #include <kmessagebox.h> | 37 | #include <kmessagebox.h> |
38 | #include <libkcal/syncdefines.h> | 38 | #include <libkcal/syncdefines.h> |
39 | 39 | ||
40 | 40 | ||
41 | #ifdef CONFIG_KWALLETIF | 41 | #ifdef CONFIG_KWALLETIF |
42 | # include "kwalletemu.h" | 42 | # include "kwalletemu.h" |
43 | #endif // CONFIG_KWALLETIF | 43 | #endif // CONFIG_KWALLETIF |
44 | 44 | ||
45 | #include <qdatetime.h> | 45 | #include <qdatetime.h> |
46 | #include <qsize.h> | 46 | #include <qsize.h> |
47 | #include <qfileinfo.h> | 47 | #include <qfileinfo.h> |
48 | #include <qfile.h> | 48 | #include <qfile.h> |
49 | 49 | ||
50 | #include <stdio.h> | 50 | #include <stdio.h> |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> |
52 | #include <errno.h> | 52 | #include <errno.h> |
53 | #include <string.h> | 53 | #include <string.h> |
54 | //US#include <iostream> | 54 | //US#include <iostream> |
55 | #include <algorithm> | 55 | #include <algorithm> |
56 | #include <sys/types.h> | 56 | #include <sys/types.h> |
57 | #include <sys/stat.h> | 57 | #include <sys/stat.h> |
58 | #include <unistd.h> | 58 | #include <unistd.h> |
59 | #include <stdint.h> | 59 | #include <stdint.h> |
60 | 60 | ||
61 | 61 | ||
62 | #ifdef PWM_EMBEDDED | 62 | #ifdef PWM_EMBEDDED |
63 | #ifndef Q_LONG | 63 | #ifndef Q_LONG |
64 | #define Q_LONG long | 64 | #define Q_LONG long |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifndef Q_ULONG | 67 | #ifndef Q_ULONG |
68 | #define Q_ULONG unsigned long | 68 | #define Q_ULONG unsigned long |
69 | #endif | 69 | #endif |
70 | #endif //PWM_EMBEDDED | 70 | #endif //PWM_EMBEDDED |
71 | 71 | ||
72 | 72 | ||
73 | //TODO: reset to its normal value. | 73 | //TODO: reset to its normal value. |
74 | #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */ | 74 | #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */ |
75 | 75 | ||
76 | using namespace std; | 76 | using namespace std; |
77 | 77 | ||
78 | 78 | ||
79 | void PwMDocList::add(PwMDoc *doc, const string &id) | 79 | void PwMDocList::add(PwMDoc *doc, const string &id) |
80 | { | 80 | { |
81 | #ifdef PWM_DEBUG | 81 | #ifdef PWM_DEBUG |
82 | // check for existance of object in debug mode only. | 82 | // check for existance of object in debug mode only. |
83 | vector<listItem>::iterator begin = docList.begin(), | 83 | vector<listItem>::iterator begin = docList.begin(), |
84 | end = docList.end(), | 84 | end = docList.end(), |
85 | i = begin; | 85 | i = begin; |
86 | while (i != end) { | 86 | while (i != end) { |
87 | if (i->doc == doc) { | 87 | if (i->doc == doc) { |
88 | BUG(); | 88 | BUG(); |
89 | return; | 89 | return; |
90 | } | 90 | } |
91 | ++i; | 91 | ++i; |
92 | } | 92 | } |
93 | #endif | 93 | #endif |
94 | listItem newItem; | 94 | listItem newItem; |
95 | newItem.doc = doc; | 95 | newItem.doc = doc; |
96 | newItem.docId = id; | 96 | newItem.docId = id; |
97 | docList.push_back(newItem); | 97 | docList.push_back(newItem); |
98 | } | 98 | } |
99 | 99 | ||
100 | void PwMDocList::edit(PwMDoc *doc, const string &newId) | 100 | void PwMDocList::edit(PwMDoc *doc, const string &newId) |
101 | { | 101 | { |
102 | vector<listItem>::iterator begin = docList.begin(), | 102 | vector<listItem>::iterator begin = docList.begin(), |
103 | end = docList.end(), | 103 | end = docList.end(), |
104 | i = begin; | 104 | i = begin; |
105 | while (i != end) { | 105 | while (i != end) { |
106 | if (i->doc == doc) { | 106 | if (i->doc == doc) { |
107 | i->docId = newId; | 107 | i->docId = newId; |
108 | return; | 108 | return; |
109 | } | 109 | } |
110 | ++i; | 110 | ++i; |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | void PwMDocList::del(PwMDoc *doc) | 114 | void PwMDocList::del(PwMDoc *doc) |
115 | { | 115 | { |
116 | vector<listItem>::iterator begin = docList.begin(), | 116 | vector<listItem>::iterator begin = docList.begin(), |
117 | end = docList.end(), | 117 | end = docList.end(), |
118 | i = begin; | 118 | i = begin; |
119 | while (i != end) { | 119 | while (i != end) { |
120 | if (i->doc == doc) { | 120 | if (i->doc == doc) { |
121 | docList.erase(i); | 121 | docList.erase(i); |
122 | return; | 122 | return; |
123 | } | 123 | } |
124 | ++i; | 124 | ++i; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | bool PwMDocList::find(const string &id, listItem *ret) | 128 | bool PwMDocList::find(const string &id, listItem *ret) |
129 | { | 129 | { |
130 | vector<listItem>::iterator begin = docList.begin(), | 130 | vector<listItem>::iterator begin = docList.begin(), |
131 | end = docList.end(), | 131 | end = docList.end(), |
132 | i = begin; | 132 | i = begin; |
133 | while (i != end) { | 133 | while (i != end) { |
134 | if (i->docId == id) { | 134 | if (i->docId == id) { |
135 | if (ret) | 135 | if (ret) |
136 | *ret = *i; | 136 | *ret = *i; |
137 | return true; | 137 | return true; |
138 | } | 138 | } |
139 | ++i; | 139 | ++i; |
140 | } | 140 | } |
141 | return false; | 141 | return false; |
142 | } | 142 | } |
143 | 143 | ||
144 | 144 | ||
145 | 145 | ||
146 | DocTimer::DocTimer(PwMDoc *_doc) | 146 | DocTimer::DocTimer(PwMDoc *_doc) |
147 | : doc (_doc) | 147 | : doc (_doc) |
148 | , mpwLock (0) | 148 | , mpwLock (0) |
149 | , autoLockLock (0) | 149 | , autoLockLock (0) |
150 | , metaCheckLock (0) | 150 | , metaCheckLock (0) |
151 | { | 151 | { |
152 | mpwTimer = new QTimer; | 152 | mpwTimer = new QTimer; |
153 | autoLockTimer = new QTimer; | 153 | autoLockTimer = new QTimer; |
154 | metaCheckTimer = new QTimer; | 154 | metaCheckTimer = new QTimer; |
155 | connect(mpwTimer, SIGNAL(timeout()), | 155 | connect(mpwTimer, SIGNAL(timeout()), |
156 | this, SLOT(mpwTimeout())); | 156 | this, SLOT(mpwTimeout())); |
157 | connect(autoLockTimer, SIGNAL(timeout()), | 157 | connect(autoLockTimer, SIGNAL(timeout()), |
158 | this, SLOT(autoLockTimeout())); | 158 | this, SLOT(autoLockTimeout())); |
159 | connect(metaCheckTimer, SIGNAL(timeout()), | 159 | connect(metaCheckTimer, SIGNAL(timeout()), |
160 | this, SLOT(metaCheckTimeout())); | 160 | this, SLOT(metaCheckTimeout())); |
161 | } | 161 | } |
162 | 162 | ||
163 | DocTimer::~DocTimer() | 163 | DocTimer::~DocTimer() |
164 | { | 164 | { |
165 | delete mpwTimer; | 165 | delete mpwTimer; |
166 | delete autoLockTimer; | 166 | delete autoLockTimer; |
167 | delete metaCheckTimer; | 167 | delete metaCheckTimer; |
168 | } | 168 | } |
169 | 169 | ||
170 | void DocTimer::start(TimerIDs timer) | 170 | void DocTimer::start(TimerIDs timer) |
171 | { | 171 | { |
172 | switch (timer) { | 172 | switch (timer) { |
173 | case id_mpwTimer: | 173 | case id_mpwTimer: |
174 | if (mpwTimer->isActive()) | 174 | if (mpwTimer->isActive()) |
175 | mpwTimer->stop(); | 175 | mpwTimer->stop(); |
176 | doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); | 176 | doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); |
177 | mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); | 177 | mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); |
178 | break; | 178 | break; |
179 | case id_autoLockTimer: | 179 | case id_autoLockTimer: |
180 | if (autoLockTimer->isActive()) | 180 | if (autoLockTimer->isActive()) |
181 | autoLockTimer->stop(); | 181 | autoLockTimer->stop(); |
182 | if (conf()->confGlobLockTimeout() > 0) | 182 | if (conf()->confGlobLockTimeout() > 0) |
183 | autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); | 183 | autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); |
184 | break; | 184 | break; |
185 | case id_metaCheckTimer: | 185 | case id_metaCheckTimer: |
186 | if (metaCheckTimer->isActive()) | 186 | if (metaCheckTimer->isActive()) |
187 | metaCheckTimer->stop(); | 187 | metaCheckTimer->stop(); |
188 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); | 188 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); |
189 | break; | 189 | break; |
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
193 | void DocTimer::stop(TimerIDs timer) | 193 | void DocTimer::stop(TimerIDs timer) |
194 | { | 194 | { |
195 | switch (timer) { | 195 | switch (timer) { |
196 | case id_mpwTimer: | 196 | case id_mpwTimer: |
197 | mpwTimer->stop(); | 197 | mpwTimer->stop(); |
198 | break; | 198 | break; |
199 | case id_autoLockTimer: | 199 | case id_autoLockTimer: |
200 | autoLockTimer->stop(); | 200 | autoLockTimer->stop(); |
201 | break; | 201 | break; |
202 | case id_metaCheckTimer: | 202 | case id_metaCheckTimer: |
203 | metaCheckTimer->stop(); | 203 | metaCheckTimer->stop(); |
204 | break; | 204 | break; |
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
208 | void DocTimer::getLock(TimerIDs timer) | 208 | void DocTimer::getLock(TimerIDs timer) |
209 | { | 209 | { |
210 | switch (timer) { | 210 | switch (timer) { |
211 | case id_mpwTimer: | 211 | case id_mpwTimer: |
212 | ++mpwLock; | 212 | ++mpwLock; |
213 | break; | 213 | break; |
214 | case id_autoLockTimer: | 214 | case id_autoLockTimer: |
215 | ++autoLockLock; | 215 | ++autoLockLock; |
216 | break; | 216 | break; |
217 | case id_metaCheckTimer: | 217 | case id_metaCheckTimer: |
218 | ++metaCheckLock; | 218 | ++metaCheckLock; |
219 | break; | 219 | break; |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
223 | void DocTimer::putLock(TimerIDs timer) | 223 | void DocTimer::putLock(TimerIDs timer) |
224 | { | 224 | { |
225 | switch (timer) { | 225 | switch (timer) { |
226 | case id_mpwTimer: | 226 | case id_mpwTimer: |
227 | if (mpwLock) | 227 | if (mpwLock) |
228 | --mpwLock; | 228 | --mpwLock; |
229 | break; | 229 | break; |
230 | case id_autoLockTimer: | 230 | case id_autoLockTimer: |
231 | if (autoLockLock) | 231 | if (autoLockLock) |
232 | --autoLockLock; | 232 | --autoLockLock; |
233 | break; | 233 | break; |
234 | case id_metaCheckTimer: | 234 | case id_metaCheckTimer: |
235 | if (metaCheckLock) | 235 | if (metaCheckLock) |
236 | --metaCheckLock; | 236 | --metaCheckLock; |
237 | break; | 237 | break; |
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
241 | void DocTimer::mpwTimeout() | 241 | void DocTimer::mpwTimeout() |
242 | { | 242 | { |
243 | if (mpwLock) { | 243 | if (mpwLock) { |
244 | mpwTimer->start(1000, true); | 244 | mpwTimer->start(1000, true); |
245 | return; | 245 | return; |
246 | } | 246 | } |
247 | doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); | 247 | doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); |
248 | } | 248 | } |
249 | 249 | ||
250 | void DocTimer::autoLockTimeout() | 250 | void DocTimer::autoLockTimeout() |
251 | { | 251 | { |
252 | if (autoLockLock) { | 252 | if (autoLockLock) { |
253 | autoLockTimer->start(1000, true); | 253 | autoLockTimer->start(1000, true); |
254 | return; | 254 | return; |
255 | } | 255 | } |
256 | if (conf()->confGlobAutoDeepLock() && | 256 | if (conf()->confGlobAutoDeepLock() && |
257 | doc->filename != QString::null && | 257 | doc->filename != QString::null && |
258 | doc->filename != "") { | 258 | doc->filename != "") { |
259 | doc->deepLock(true); | 259 | doc->deepLock(true); |
260 | } else { | 260 | } else { |
261 | doc->lockAll(true); | 261 | doc->lockAll(true); |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | void DocTimer::metaCheckTimeout() | 265 | void DocTimer::metaCheckTimeout() |
266 | { | 266 | { |
267 | if (metaCheckLock) { | 267 | if (metaCheckLock) { |
268 | // check again in one second. | 268 | // check again in one second. |
269 | metaCheckTimer->start(1000, true); | 269 | metaCheckTimer->start(1000, true); |
270 | return; | 270 | return; |
271 | } | 271 | } |
272 | if (doc->isDeepLocked()) { | 272 | if (doc->isDeepLocked()) { |
273 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); | 273 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); |
274 | return; | 274 | return; |
275 | } | 275 | } |
276 | if (doc->isDocEmpty()) { | 276 | if (doc->isDocEmpty()) { |
277 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); | 277 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); |
278 | return; | 278 | return; |
279 | } | 279 | } |
280 | #ifdef CONFIG_KWALLETIF | 280 | #ifdef CONFIG_KWALLETIF |
281 | KWalletEmu *kwlEmu = doc->init->kwalletEmu(); | 281 | KWalletEmu *kwlEmu = doc->init->kwalletEmu(); |
282 | if (kwlEmu) | 282 | if (kwlEmu) |
283 | kwlEmu->suspendDocSignals(); | 283 | kwlEmu->suspendDocSignals(); |
284 | #endif // CONFIG_KWALLETIF | 284 | #endif // CONFIG_KWALLETIF |
285 | /* We simply trigger all views to update their | 285 | /* We simply trigger all views to update their |
286 | * displayed values. This way they have a chance | 286 | * displayed values. This way they have a chance |
287 | * to get notified when some meta changes over time. | 287 | * to get notified when some meta changes over time. |
288 | * (for example an entry expired). | 288 | * (for example an entry expired). |
289 | * The _view_ is responsive for not updating its | 289 | * The _view_ is responsive for not updating its |
290 | * contents if nothing really changed! | 290 | * contents if nothing really changed! |
291 | */ | 291 | */ |
292 | emit doc->dataChanged(doc); | 292 | emit doc->dataChanged(doc); |
293 | #ifdef CONFIG_KWALLETIF | 293 | #ifdef CONFIG_KWALLETIF |
294 | if (kwlEmu) | 294 | if (kwlEmu) |
295 | kwlEmu->resumeDocSignals(); | 295 | kwlEmu->resumeDocSignals(); |
296 | #endif // CONFIG_KWALLETIF | 296 | #endif // CONFIG_KWALLETIF |
297 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); | 297 | metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); |
298 | } | 298 | } |
299 | 299 | ||
300 | 300 | ||
301 | 301 | ||
302 | PwMDocList PwMDoc::openDocList; | 302 | PwMDocList PwMDoc::openDocList; |
303 | unsigned int PwMDocList::unnamedDocCnt = 1; | 303 | unsigned int PwMDocList::unnamedDocCnt = 1; |
304 | 304 | ||
305 | PwMDoc::PwMDoc(QObject *parent, const char *name) | 305 | PwMDoc::PwMDoc(QObject *parent, const char *name) |
306 | : PwMDocUi(parent, name) | 306 | : PwMDocUi(parent, name) |
307 | , dataChangedLock (0) | 307 | , dataChangedLock (0) |
308 | { | 308 | { |
309 | deleted = false; | 309 | deleted = false; |
310 | unnamedNum = 0; | 310 | unnamedNum = 0; |
311 | getOpenDocList()->add(this, getTitle().latin1()); | 311 | getOpenDocList()->add(this, getTitle().latin1()); |
312 | curDocStat = 0; | 312 | curDocStat = 0; |
313 | setMaxNumEntries(); | 313 | setMaxNumEntries(); |
314 | _timer = new DocTimer(this); | 314 | _timer = new DocTimer(this); |
315 | timer()->start(DocTimer::id_mpwTimer); | 315 | timer()->start(DocTimer::id_mpwTimer); |
316 | timer()->start(DocTimer::id_autoLockTimer); | 316 | timer()->start(DocTimer::id_autoLockTimer); |
317 | timer()->start(DocTimer::id_metaCheckTimer); | 317 | timer()->start(DocTimer::id_metaCheckTimer); |
318 | addCategory(DEFAULT_CATEGORY, 0, false); | 318 | addCategory(DEFAULT_CATEGORY, 0, false); |
319 | listView = 0; | 319 | listView = 0; |
320 | emit docCreated(this); | 320 | emit docCreated(this); |
321 | } | 321 | } |
322 | 322 | ||
323 | PwMDoc::~PwMDoc() | 323 | PwMDoc::~PwMDoc() |
324 | { | 324 | { |
325 | emit docClosed(this); | 325 | emit docClosed(this); |
326 | getOpenDocList()->del(this); | 326 | getOpenDocList()->del(this); |
327 | delete _timer; | 327 | delete _timer; |
328 | } | 328 | } |
329 | 329 | ||
330 | PwMerror PwMDoc::saveDoc(char compress, const QString *file) | 330 | PwMerror PwMDoc::saveDoc(char compress, const QString *file) |
331 | { | 331 | { |
332 | PwMerror ret, e; | 332 | PwMerror ret, e; |
333 | string serialized; | ||
334 | QFile f; | ||
335 | QString tmpFileMoved(QString::null); | ||
336 | bool wasDeepLocked; | ||
337 | QString savedFilename(filename); | ||
338 | |||
333 | if (!file) { | 339 | if (!file) { |
334 | if (filename == "") | 340 | if (filename == "") |
335 | return e_filename; | 341 | return e_filename; |
336 | } else { | 342 | if (isDeepLocked()) { |
343 | /* We don't need to save any data. | ||
344 | * It's already all on disk, because | ||
345 | * we are deeplocked. | ||
346 | */ | ||
347 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); | ||
348 | ret = e_success; | ||
349 | goto out; | ||
350 | } | ||
351 | } else { | ||
337 | if (*file == "" && filename == "") | 352 | if (*file == "" && filename == "") |
338 | return e_filename; | 353 | return e_filename; |
339 | if (*file != "") | 354 | if (*file != "") |
340 | filename = *file; | 355 | filename = *file; |
341 | } | 356 | } |
342 | 357 | ||
343 | bool wasDeepLocked = isDeepLocked(); | 358 | wasDeepLocked = isDeepLocked(); |
344 | if (wasDeepLocked) { | 359 | if (wasDeepLocked) { |
345 | if (deepLock(false) != e_success) | 360 | /* We are deeplocked. That means all data is already |
346 | return e_noPw; | 361 | * on disk. BUT we need to do saving procedure, |
362 | * because *file != savedFilename. | ||
363 | * Additionally we need to tempoarly restore | ||
364 | * the old "filename", because deepLock() references it. | ||
365 | */ | ||
366 | QString newFilename(filename); | ||
367 | filename = savedFilename; | ||
368 | getDataChangedLock(); | ||
369 | e = deepLock(false); | ||
370 | putDataChangedLock(); | ||
371 | filename = newFilename; | ||
372 | switch (e) { | ||
373 | case e_success: | ||
374 | break; | ||
375 | case e_wrongPw: | ||
376 | case e_noPw: | ||
377 | emitDataChanged(this); | ||
378 | return e; | ||
379 | default: | ||
380 | emitDataChanged(this); | ||
381 | return e_openFile; | ||
382 | } | ||
347 | } | 383 | } |
348 | 384 | ||
349 | if (!isPwAvailable()) { | 385 | if (!isPwAvailable()) { |
350 | /* password is not available. This means, the | 386 | /* password is not available. This means, the |
351 | * document wasn't saved, yet. | 387 | * document wasn't saved, yet. |
352 | */ | 388 | */ |
353 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); | 389 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); |
354 | QString pw(requestNewMpw(&useChipcard)); | 390 | QString pw(requestNewMpw(&useChipcard)); |
355 | if (pw != "") { | 391 | if (pw != "") { |
356 | currentPw = pw; | 392 | currentPw = pw; |
357 | } else { | 393 | } else { |
358 | return e_noPw; | 394 | return e_noPw; |
359 | } | 395 | } |
360 | if (useChipcard) { | 396 | if (useChipcard) { |
361 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); | 397 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); |
362 | } else { | 398 | } else { |
363 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); | 399 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); |
364 | } | 400 | } |
365 | } | 401 | } |
366 | 402 | ||
367 | int _cryptAlgo = conf()->confGlobCryptAlgo(); | 403 | int _cryptAlgo = conf()->confGlobCryptAlgo(); |
368 | int _hashAlgo = conf()->confGlobHashAlgo(); | 404 | int _hashAlgo = conf()->confGlobHashAlgo(); |
369 | 405 | ||
370 | // sanity check for the selected algorithms | 406 | // sanity check for the selected algorithms |
371 | if (_cryptAlgo < PWM_CRYPT_BLOWFISH || | 407 | if (_cryptAlgo < PWM_CRYPT_BLOWFISH || |
372 | _cryptAlgo > PWM_CRYPT_TWOFISH128) { | 408 | _cryptAlgo > PWM_CRYPT_TWOFISH128) { |
373 | printWarn("Invalid Crypto-Algorithm selected! " | 409 | printWarn("Invalid Crypto-Algorithm selected! " |
374 | "Config-file seems to be corrupt. " | 410 | "Config-file seems to be corrupt. " |
375 | "Falling back to Blowfish."); | 411 | "Falling back to Blowfish."); |
376 | _cryptAlgo = PWM_CRYPT_BLOWFISH; | 412 | _cryptAlgo = PWM_CRYPT_BLOWFISH; |
377 | } | 413 | } |
378 | if (_hashAlgo < PWM_HASH_SHA1 || | 414 | if (_hashAlgo < PWM_HASH_SHA1 || |
379 | _hashAlgo > PWM_HASH_TIGER) { | 415 | _hashAlgo > PWM_HASH_TIGER) { |
380 | printWarn("Invalid Hash-Algorithm selected! " | 416 | printWarn("Invalid Hash-Algorithm selected! " |
381 | "Config-file seems to be corrupt. " | 417 | "Config-file seems to be corrupt. " |
382 | "Falling back to SHA1."); | 418 | "Falling back to SHA1."); |
383 | _hashAlgo = PWM_HASH_SHA1; | 419 | _hashAlgo = PWM_HASH_SHA1; |
384 | } | 420 | } |
385 | char cryptAlgo = static_cast<char>(_cryptAlgo); | 421 | char cryptAlgo = static_cast<char>(_cryptAlgo); |
386 | char hashAlgo = static_cast<char>(_hashAlgo); | 422 | char hashAlgo = static_cast<char>(_hashAlgo); |
387 | 423 | ||
388 | if (conf()->confGlobMakeFileBackup()) { | 424 | if (conf()->confGlobMakeFileBackup()) { |
389 | if (!backupFile(filename)) | 425 | if (!backupFile(filename)) |
390 | return e_fileBackup; | 426 | return e_fileBackup; |
391 | } | 427 | } |
392 | QString tmpFileMoved(QString::null); | ||
393 | if (QFile::exists(filename)) { | 428 | if (QFile::exists(filename)) { |
394 | /* Move the existing file to some tmp file. | 429 | /* Move the existing file to some tmp file. |
395 | * When saving file succeeds, delete tmp file. Otherwise | 430 | * When saving file succeeds, delete tmp file. Otherwise |
396 | * move tmp file back. See below. | 431 | * move tmp file back. See below. |
397 | */ | 432 | */ |
398 | Randomizer *rnd = Randomizer::obj(); | 433 | Randomizer *rnd = Randomizer::obj(); |
399 | char rnd_buf[5]; | 434 | char rnd_buf[5]; |
400 | sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, | 435 | sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, |
401 | rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); | 436 | rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); |
402 | tmpFileMoved = filename + "." + rnd_buf + ".mv"; | 437 | tmpFileMoved = filename + "." + rnd_buf + ".mv"; |
403 | if (!copyFile(filename, tmpFileMoved)) | 438 | if (!copyFile(filename, tmpFileMoved)) |
404 | return e_openFile; | 439 | return e_openFile; |
405 | if (!QFile::remove(filename)) { | 440 | if (!QFile::remove(filename)) { |
406 | printWarn(string("removing orig file ") | 441 | printWarn(string("removing orig file ") |
407 | + filename.latin1() | 442 | + filename.latin1() |
408 | + " failed!"); | 443 | + " failed!"); |
409 | } | 444 | } |
410 | } | 445 | } |
411 | QFile f(filename); | 446 | f.setName(filename); |
412 | string serialized; | ||
413 | if (!f.open(IO_ReadWrite)) { | 447 | if (!f.open(IO_ReadWrite)) { |
414 | ret = e_openFile; | 448 | ret = e_openFile; |
415 | goto out_moveback; | 449 | goto out_moveback; |
416 | } | 450 | } |
417 | e = writeFileHeader(hashAlgo, hashAlgo, | 451 | e = writeFileHeader(hashAlgo, hashAlgo, |
418 | cryptAlgo, compress, | 452 | cryptAlgo, compress, |
419 | ¤tPw, &f); | 453 | ¤tPw, &f); |
420 | if (e == e_hashNotImpl) { | 454 | if (e == e_hashNotImpl) { |
421 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); | 455 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); |
422 | f.close(); | 456 | f.close(); |
423 | ret = e_hashNotImpl; | 457 | ret = e_hashNotImpl; |
424 | goto out_moveback; | 458 | goto out_moveback; |
425 | } else if (e != e_success) { | 459 | } else if (e != e_success) { |
426 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); | 460 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); |
427 | f.close(); | 461 | f.close(); |
428 | ret = e_writeHeader; | 462 | ret = e_writeHeader; |
429 | goto out_moveback; | 463 | goto out_moveback; |
430 | } | 464 | } |
431 | if (!serializeDta(&serialized)) { | 465 | if (!serializeDta(&serialized)) { |
432 | printDebug("PwMDoc::saveDoc(): serializeDta() failed"); | 466 | printDebug("PwMDoc::saveDoc(): serializeDta() failed"); |
433 | f.close(); | 467 | f.close(); |
434 | ret = e_serializeDta; | 468 | ret = e_serializeDta; |
435 | goto out_moveback; | 469 | goto out_moveback; |
436 | } | 470 | } |
437 | e = writeDataHash(hashAlgo, &serialized, &f); | 471 | e = writeDataHash(hashAlgo, &serialized, &f); |
438 | if (e == e_hashNotImpl) { | 472 | if (e == e_hashNotImpl) { |
439 | printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); | 473 | printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); |
440 | f.close(); | 474 | f.close(); |
441 | ret = e_hashNotImpl; | 475 | ret = e_hashNotImpl; |
442 | goto out_moveback; | 476 | goto out_moveback; |
443 | } else if (e != e_success) { | 477 | } else if (e != e_success) { |
444 | printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); | 478 | printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); |
445 | f.close(); | 479 | f.close(); |
446 | ret = e_writeHeader; | 480 | ret = e_writeHeader; |
447 | goto out_moveback; | 481 | goto out_moveback; |
448 | } | 482 | } |
449 | if (!compressDta(&serialized, compress)) { | 483 | if (!compressDta(&serialized, compress)) { |
450 | printDebug("PwMDoc::saveDoc(): compressDta() failed"); | 484 | printDebug("PwMDoc::saveDoc(): compressDta() failed"); |
451 | f.close(); | 485 | f.close(); |
452 | ret = e_enc; | 486 | ret = e_enc; |
453 | goto out_moveback; | 487 | goto out_moveback; |
454 | } | 488 | } |
455 | e = encrypt(&serialized, ¤tPw, &f, cryptAlgo); | 489 | e = encrypt(&serialized, ¤tPw, &f, cryptAlgo); |
456 | if (e == e_weakPw) { | 490 | if (e == e_weakPw) { |
457 | printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); | 491 | printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); |
458 | f.close(); | 492 | f.close(); |
459 | ret = e_weakPw; | 493 | ret = e_weakPw; |
460 | goto out_moveback; | 494 | goto out_moveback; |
461 | } else if (e == e_cryptNotImpl) { | 495 | } else if (e == e_cryptNotImpl) { |
462 | printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); | 496 | printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); |
463 | f.close(); | 497 | f.close(); |
464 | ret = e_cryptNotImpl; | 498 | ret = e_cryptNotImpl; |
465 | goto out_moveback; | 499 | goto out_moveback; |
466 | } else if (e != e_success) { | 500 | } else if (e != e_success) { |
467 | printDebug("PwMDoc::saveDoc(): encrypt() failed"); | 501 | printDebug("PwMDoc::saveDoc(): encrypt() failed"); |
468 | f.close(); | 502 | f.close(); |
469 | ret = e_enc; | 503 | ret = e_enc; |
470 | goto out_moveback; | 504 | goto out_moveback; |
471 | } | 505 | } |
472 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); | 506 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); |
473 | f.close(); | 507 | f.close(); |
474 | if (chmod(filename.latin1(), | 508 | if (chmod(filename.latin1(), |
475 | conf()->confGlobFilePermissions())) { | 509 | conf()->confGlobFilePermissions())) { |
476 | printWarn(string("chmod failed: ") + strerror(errno)); | 510 | printWarn(string("chmod failed: ") + strerror(errno)); |
477 | } | 511 | } |
478 | openDocList.edit(this, getTitle().latin1()); | 512 | openDocList.edit(this, getTitle().latin1()); |
479 | if (wasDeepLocked) | 513 | if (wasDeepLocked) { |
480 | deepLock(true); | 514 | /* Do _not_ save the data with the deepLock() |
515 | * call, because this will recurse | ||
516 | * into saveDoc() | ||
517 | */ | ||
518 | deepLock(true, false); | ||
519 | /* We don't check return value here, because | ||
520 | * it won't fail. See NOTE in deepLock() | ||
521 | */ | ||
522 | } | ||
481 | if (tmpFileMoved != QString::null) { | 523 | if (tmpFileMoved != QString::null) { |
482 | // now remove the moved file. | 524 | // now remove the moved file. |
483 | if (!QFile::remove(tmpFileMoved)) { | 525 | if (!QFile::remove(tmpFileMoved)) { |
484 | printWarn(string("removing file ") | 526 | printWarn(string("removing file ") |
485 | + tmpFileMoved.latin1() | 527 | + tmpFileMoved.latin1() |
486 | + " failed!"); | 528 | + " failed!"); |
487 | } | 529 | } |
488 | } | 530 | } |
489 | ret = e_success; | 531 | ret = e_success; |
490 | printDebug(string("writing file { name: ") | 532 | printDebug(string("writing file { name: ") |
491 | + filename.latin1() + " compress: " | 533 | + filename.latin1() + " compress: " |
492 | + tostr(static_cast<int>(compress)) + " cryptAlgo: " | 534 | + tostr(static_cast<int>(compress)) + " cryptAlgo: " |
493 | + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " | 535 | + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " |
494 | + tostr(static_cast<int>(hashAlgo)) | 536 | + tostr(static_cast<int>(hashAlgo)) |
495 | + " }"); | 537 | + " }"); |
496 | goto out; | 538 | goto out; |
497 | out_moveback: | 539 | out_moveback: |
498 | if (tmpFileMoved != QString::null) { | 540 | if (tmpFileMoved != QString::null) { |
499 | if (copyFile(tmpFileMoved, filename)) { | 541 | if (copyFile(tmpFileMoved, filename)) { |
500 | if (!QFile::remove(tmpFileMoved)) { | 542 | if (!QFile::remove(tmpFileMoved)) { |
501 | printWarn(string("removing tmp file ") | 543 | printWarn(string("removing tmp file ") |
502 | + filename.latin1() | 544 | + filename.latin1() |
503 | + " failed!"); | 545 | + " failed!"); |
504 | } | 546 | } |
505 | } else { | 547 | } else { |
506 | printWarn(string("couldn't copy file ") | 548 | printWarn(string("couldn't copy file ") |
507 | + tmpFileMoved.latin1() | 549 | + tmpFileMoved.latin1() |
508 | + " back to " | 550 | + " back to " |
509 | + filename.latin1()); | 551 | + filename.latin1()); |
510 | } | 552 | } |
511 | } | 553 | } |
512 | out: | 554 | out: |
513 | return ret; | 555 | return ret; |
514 | } | 556 | } |
515 | 557 | ||
516 | PwMerror PwMDoc::openDoc(const QString *file, int openLocked) | 558 | PwMerror PwMDoc::openDoc(const QString *file, int openLocked) |
517 | { | 559 | { |
518 | PWM_ASSERT(file); | 560 | PWM_ASSERT(file); |
519 | PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); | 561 | PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); |
520 | string decrypted, dataHash; | 562 | string decrypted, dataHash; |
521 | PwMerror ret; | 563 | PwMerror ret; |
522 | char cryptAlgo, dataHashType, compress; | 564 | char cryptAlgo, dataHashType, compress; |
523 | unsigned int headerLen; | 565 | unsigned int headerLen; |
524 | 566 | ||
525 | if (*file == "") | 567 | if (*file == "") |
526 | return e_readFile; | 568 | return e_readFile; |
527 | filename = *file; | 569 | filename = *file; |
528 | /* check if this file is already open. | 570 | /* check if this file is already open. |
529 | * This does not catch symlinks! | 571 | * This does not catch symlinks! |
530 | */ | 572 | */ |
531 | if (!isDeepLocked()) { | 573 | if (!isDeepLocked()) { |
532 | if (getOpenDocList()->find(filename.latin1())) | 574 | if (getOpenDocList()->find(filename.latin1())) |
533 | return e_alreadyOpen; | 575 | return e_alreadyOpen; |
534 | } | 576 | } |
535 | QFile f(filename); | 577 | QFile f(filename); |
536 | 578 | ||
537 | if (openLocked == 2) { | 579 | if (openLocked == 2) { |
538 | // open deep-locked | 580 | // open deep-locked |
539 | if (!QFile::exists(filename)) | 581 | if (!QFile::exists(filename)) |
540 | return e_openFile; | 582 | return e_openFile; |
541 | if (deepLock(true, false) != e_success) | 583 | if (deepLock(true, false) != e_success) |
542 | return e_openFile; | 584 | return e_openFile; |
543 | goto out_success; | 585 | goto out_success; |
544 | } | 586 | } |
545 | 587 | ||
546 | if (!f.open(IO_ReadOnly)) | 588 | if (!f.open(IO_ReadOnly)) |
547 | return e_openFile; | 589 | return e_openFile; |
548 | 590 | ||
549 | ret = checkHeader(&cryptAlgo, ¤tPw, &compress, &headerLen, | 591 | ret = checkHeader(&cryptAlgo, ¤tPw, &compress, &headerLen, |
550 | &dataHashType, &dataHash, &f); | 592 | &dataHashType, &dataHash, &f); |
551 | if (ret != e_success) { | 593 | if (ret != e_success) { |
552 | printDebug("PwMDoc::openDoc(): checkHeader() failed"); | 594 | printDebug("PwMDoc::openDoc(): checkHeader() failed"); |
553 | f.close(); | 595 | f.close(); |
554 | if (ret == e_wrongPw) { | 596 | if (ret == e_wrongPw) { |
555 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 597 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
556 | return ret; | 598 | return ret; |
557 | } else if (ret == e_noPw || | 599 | } else if (ret == e_noPw || |
558 | ret == e_fileVer || | 600 | ret == e_fileVer || |
559 | ret == e_fileFormat || | 601 | ret == e_fileFormat || |
560 | ret == e_hashNotImpl) { | 602 | ret == e_hashNotImpl) { |
561 | return ret; | 603 | return ret; |
562 | } else | 604 | } else |
563 | return e_readFile; | 605 | return e_readFile; |
564 | } | 606 | } |
565 | ret = decrypt(&decrypted, headerLen, ¤tPw, cryptAlgo, &f); | 607 | ret = decrypt(&decrypted, headerLen, ¤tPw, cryptAlgo, &f); |
566 | if (ret == e_cryptNotImpl) { | 608 | if (ret == e_cryptNotImpl) { |
567 | printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); | 609 | printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); |
568 | f.close(); | 610 | f.close(); |
569 | return e_cryptNotImpl; | 611 | return e_cryptNotImpl; |
570 | } else if (ret != e_success) { | 612 | } else if (ret != e_success) { |
571 | printDebug("PwMDoc::openDoc(): decrypt() failed"); | 613 | printDebug("PwMDoc::openDoc(): decrypt() failed"); |
572 | f.close(); | 614 | f.close(); |
573 | return e_readFile; | 615 | return e_readFile; |
574 | } | 616 | } |
575 | if (!decompressDta(&decrypted, compress)) { | 617 | if (!decompressDta(&decrypted, compress)) { |
576 | printDebug("PwMDoc::openDoc(): decompressDta() failed"); | 618 | printDebug("PwMDoc::openDoc(): decompressDta() failed"); |
577 | f.close(); | 619 | f.close(); |
578 | return e_fileCorrupt; | 620 | return e_fileCorrupt; |
579 | } | 621 | } |
580 | ret = checkDataHash(dataHashType, &dataHash, &decrypted); | 622 | ret = checkDataHash(dataHashType, &dataHash, &decrypted); |
581 | if (ret == e_hashNotImpl) { | 623 | if (ret == e_hashNotImpl) { |
582 | printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); | 624 | printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); |
583 | f.close(); | 625 | f.close(); |
584 | return e_hashNotImpl; | 626 | return e_hashNotImpl; |
585 | } else if (ret != e_success) { | 627 | } else if (ret != e_success) { |
586 | printDebug("PwMDoc::openDoc(): checkDataHash() failed"); | 628 | printDebug("PwMDoc::openDoc(): checkDataHash() failed"); |
587 | f.close(); | 629 | f.close(); |
588 | return e_fileCorrupt; | 630 | return e_fileCorrupt; |
589 | } | 631 | } |
590 | if (!deSerializeDta(&decrypted, openLocked == 1)) { | 632 | if (!deSerializeDta(&decrypted, openLocked == 1)) { |
591 | printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); | 633 | printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); |
592 | f.close(); | 634 | f.close(); |
593 | return e_readFile; | 635 | return e_readFile; |
594 | } | 636 | } |
595 | f.close(); | 637 | f.close(); |
596 | timer()->start(DocTimer::id_mpwTimer); | 638 | timer()->start(DocTimer::id_mpwTimer); |
597 | timer()->start(DocTimer::id_autoLockTimer); | 639 | timer()->start(DocTimer::id_autoLockTimer); |
598 | out_success: | 640 | out_success: |
599 | openDocList.edit(this, getTitle().latin1()); | 641 | openDocList.edit(this, getTitle().latin1()); |
600 | emit docOpened(this); | 642 | emit docOpened(this); |
601 | return e_success; | 643 | return e_success; |
602 | } | 644 | } |
603 | 645 | ||
604 | PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, | 646 | PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, |
605 | QString *pw, QFile *f) | 647 | QString *pw, QFile *f) |
606 | { | 648 | { |
607 | PWM_ASSERT(pw); | 649 | PWM_ASSERT(pw); |
608 | PWM_ASSERT(f); | 650 | PWM_ASSERT(f); |
609 | //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else | 651 | //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else |
610 | //Wenn I sync, I open a doc without a view => listView is 0 => Assertion | 652 | //Wenn I sync, I open a doc without a view => listView is 0 => Assertion |
611 | //USPWM_ASSERT(listView); | 653 | //USPWM_ASSERT(listView); |
612 | if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != | 654 | if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != |
613 | static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { | 655 | static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { |
614 | return e_writeFile; | 656 | return e_writeFile; |
615 | } | 657 | } |
616 | if (f->putch(PWM_FILE_VER) == -1 || | 658 | if (f->putch(PWM_FILE_VER) == -1 || |
617 | f->putch(keyHash) == -1 || | 659 | f->putch(keyHash) == -1 || |
618 | f->putch(dataHash) == -1 || | 660 | f->putch(dataHash) == -1 || |
619 | f->putch(crypt) == -1 || | 661 | f->putch(crypt) == -1 || |
620 | f->putch(compress) == -1 || | 662 | f->putch(compress) == -1 || |
621 | f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? | 663 | f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? |
622 | (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { | 664 | (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { |
623 | return e_writeFile; | 665 | return e_writeFile; |
624 | } | 666 | } |
625 | 667 | ||
626 | // write bytes of NUL-data. These bytes are reserved for future-use. | 668 | // write bytes of NUL-data. These bytes are reserved for future-use. |
627 | const int bufSize = 64; | 669 | const int bufSize = 64; |
628 | char tmp_buf[bufSize]; | 670 | char tmp_buf[bufSize]; |
629 | memset(tmp_buf, 0x00, bufSize); | 671 | memset(tmp_buf, 0x00, bufSize); |
630 | if (f->writeBlock(tmp_buf, bufSize) != bufSize) | 672 | if (f->writeBlock(tmp_buf, bufSize) != bufSize) |
631 | return e_writeFile; | 673 | return e_writeFile; |
632 | 674 | ||
633 | switch (keyHash) { | 675 | switch (keyHash) { |
634 | case PWM_HASH_SHA1: { | 676 | case PWM_HASH_SHA1: { |
635 | const int hashlen = SHA1_HASH_LEN_BYTE; | 677 | const int hashlen = SHA1_HASH_LEN_BYTE; |
636 | Sha1 hash; | 678 | Sha1 hash; |
637 | hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); | 679 | hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); |
638 | string ret = hash.sha1_read(); | 680 | string ret = hash.sha1_read(); |
639 | if (f->writeBlock(ret.c_str(), hashlen) != hashlen) | 681 | if (f->writeBlock(ret.c_str(), hashlen) != hashlen) |
640 | return e_writeFile; | 682 | return e_writeFile; |
641 | break; | 683 | break; |
642 | } | 684 | } |
643 | case PWM_HASH_SHA256: | 685 | case PWM_HASH_SHA256: |
644 | /*... fall through */ | 686 | /*... fall through */ |
645 | case PWM_HASH_SHA384: | 687 | case PWM_HASH_SHA384: |
646 | case PWM_HASH_SHA512: | 688 | case PWM_HASH_SHA512: |
647 | case PWM_HASH_MD5: | 689 | case PWM_HASH_MD5: |
648 | case PWM_HASH_RMD160: | 690 | case PWM_HASH_RMD160: |
649 | case PWM_HASH_TIGER: | 691 | case PWM_HASH_TIGER: |
650 | { | 692 | { |
651 | if (!LibGCryptIf::available()) | 693 | if (!LibGCryptIf::available()) |
652 | return e_hashNotImpl; | 694 | return e_hashNotImpl; |
653 | LibGCryptIf gc; | 695 | LibGCryptIf gc; |
654 | PwMerror err; | 696 | PwMerror err; |
655 | unsigned char *buf; | 697 | unsigned char *buf; |
656 | size_t hashLen; | 698 | size_t hashLen; |
657 | err = gc.hash(&buf, | 699 | err = gc.hash(&buf, |
658 | &hashLen, | 700 | &hashLen, |
659 | reinterpret_cast<const unsigned char *>(pw->latin1()), | 701 | reinterpret_cast<const unsigned char *>(pw->latin1()), |
660 | pw->length(), | 702 | pw->length(), |
661 | keyHash); | 703 | keyHash); |
662 | if (err != e_success) | 704 | if (err != e_success) |
663 | return e_hashNotImpl; | 705 | return e_hashNotImpl; |
664 | if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) | 706 | if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) |
665 | != static_cast<Q_LONG>(hashLen)) { | 707 | != static_cast<Q_LONG>(hashLen)) { |
666 | delete [] buf; | 708 | delete [] buf; |
667 | return e_hashNotImpl; | 709 | return e_hashNotImpl; |
668 | } | 710 | } |
669 | delete [] buf; | 711 | delete [] buf; |
670 | break; | 712 | break; |
671 | } | 713 | } |
672 | default: { | 714 | default: { |
673 | return e_hashNotImpl; | 715 | return e_hashNotImpl; |
674 | } } | 716 | } } |
675 | return e_success; | 717 | return e_success; |
676 | } | 718 | } |
677 | 719 | ||
678 | PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, | 720 | PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, |
679 | unsigned int *headerLength, char *dataHashType, | 721 | unsigned int *headerLength, char *dataHashType, |
680 | string *dataHash, QFile *f) | 722 | string *dataHash, QFile *f) |
681 | { | 723 | { |
682 | PWM_ASSERT(cryptAlgo); | 724 | PWM_ASSERT(cryptAlgo); |
683 | PWM_ASSERT(pw); | 725 | PWM_ASSERT(pw); |
684 | PWM_ASSERT(headerLength); | 726 | PWM_ASSERT(headerLength); |
685 | PWM_ASSERT(dataHashType); | 727 | PWM_ASSERT(dataHashType); |
686 | PWM_ASSERT(dataHash); | 728 | PWM_ASSERT(dataHash); |
687 | PWM_ASSERT(f); | 729 | PWM_ASSERT(f); |
688 | int tmpRet; | 730 | int tmpRet; |
689 | // check "magic" header | 731 | // check "magic" header |
690 | const char magicHdr[] = FILE_ID_HEADER; | 732 | const char magicHdr[] = FILE_ID_HEADER; |
691 | const int hdrLen = array_size(magicHdr) - 1; | 733 | const int hdrLen = array_size(magicHdr) - 1; |
692 | char tmp[hdrLen]; | 734 | char tmp[hdrLen]; |
693 | if (f->readBlock(tmp, hdrLen) != hdrLen) | 735 | if (f->readBlock(tmp, hdrLen) != hdrLen) |
694 | return e_readFile; | 736 | return e_readFile; |
695 | if (memcmp(tmp, magicHdr, hdrLen) != 0) | 737 | if (memcmp(tmp, magicHdr, hdrLen) != 0) |
696 | return e_fileFormat; | 738 | return e_fileFormat; |
697 | // read and check file ver | 739 | // read and check file ver |
698 | int fileV = f->getch(); | 740 | int fileV = f->getch(); |
699 | if (fileV == -1) | 741 | if (fileV == -1) |
700 | return e_fileFormat; | 742 | return e_fileFormat; |
701 | if (fileV != PWM_FILE_VER) | 743 | if (fileV != PWM_FILE_VER) |
702 | return e_fileVer; | 744 | return e_fileVer; |
703 | // read hash hash type | 745 | // read hash hash type |
704 | int keyHash = f->getch(); | 746 | int keyHash = f->getch(); |
705 | if (keyHash == -1) | 747 | if (keyHash == -1) |
706 | return e_fileFormat; | 748 | return e_fileFormat; |
707 | // read data hash type | 749 | // read data hash type |
708 | tmpRet = f->getch(); | 750 | tmpRet = f->getch(); |
709 | if (tmpRet == -1) | 751 | if (tmpRet == -1) |
710 | return e_fileFormat; | 752 | return e_fileFormat; |
711 | *dataHashType = tmpRet; | 753 | *dataHashType = tmpRet; |
712 | // read crypt algo | 754 | // read crypt algo |
713 | tmpRet = f->getch(); | 755 | tmpRet = f->getch(); |
714 | if (tmpRet == -1) | 756 | if (tmpRet == -1) |
715 | return e_fileFormat; | 757 | return e_fileFormat; |
716 | *cryptAlgo = tmpRet; | 758 | *cryptAlgo = tmpRet; |
717 | // get compression-algo | 759 | // get compression-algo |
718 | tmpRet = f->getch(); | 760 | tmpRet = f->getch(); |
719 | if (tmpRet == -1) | 761 | if (tmpRet == -1) |
720 | return e_fileFormat; | 762 | return e_fileFormat; |
721 | *compress = tmpRet; | 763 | *compress = tmpRet; |
722 | // get the MPW-flag | 764 | // get the MPW-flag |
723 | int mpw_flag = f->getch(); | 765 | int mpw_flag = f->getch(); |
724 | if (mpw_flag == -1) | 766 | if (mpw_flag == -1) |
725 | return e_fileFormat; | 767 | return e_fileFormat; |
726 | if (mpw_flag == 0x01) | 768 | if (mpw_flag == 0x01) |
727 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); | 769 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); |
728 | else | 770 | else |
729 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); | 771 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); |
730 | // skip the "RESERVED"-bytes | 772 | // skip the "RESERVED"-bytes |
731 | if (!(f->at(f->at() + 64))) | 773 | if (!(f->at(f->at() + 64))) |
732 | return e_fileFormat; | 774 | return e_fileFormat; |
733 | 775 | ||
734 | *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 776 | *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
735 | if (*pw == "") { | 777 | if (*pw == "") { |
736 | /* the user didn't give a master-password | 778 | /* the user didn't give a master-password |
737 | * or didn't insert a chipcard | 779 | * or didn't insert a chipcard |
738 | */ | 780 | */ |
739 | return e_noPw; | 781 | return e_noPw; |
740 | } | 782 | } |
741 | // verify key-hash | 783 | // verify key-hash |
742 | switch (keyHash) { | 784 | switch (keyHash) { |
743 | case PWM_HASH_SHA1: { | 785 | case PWM_HASH_SHA1: { |
744 | // read hash from header | 786 | // read hash from header |
745 | const int hashLen = SHA1_HASH_LEN_BYTE; | 787 | const int hashLen = SHA1_HASH_LEN_BYTE; |
746 | string readHash; | 788 | string readHash; |
747 | int i; | 789 | int i; |
748 | for (i = 0; i < hashLen; ++i) | 790 | for (i = 0; i < hashLen; ++i) |
749 | readHash.push_back(f->getch()); | 791 | readHash.push_back(f->getch()); |
750 | Sha1 hash; | 792 | Sha1 hash; |
751 | hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); | 793 | hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); |
752 | string ret = hash.sha1_read(); | 794 | string ret = hash.sha1_read(); |
753 | if (ret != readHash) | 795 | if (ret != readHash) |
754 | return e_wrongPw;// hash doesn't match (wrong key) | 796 | return e_wrongPw;// hash doesn't match (wrong key) |
755 | break; | 797 | break; |
756 | } | 798 | } |
757 | case PWM_HASH_SHA256: | 799 | case PWM_HASH_SHA256: |
758 | /*... fall through */ | 800 | /*... fall through */ |
759 | case PWM_HASH_SHA384: | 801 | case PWM_HASH_SHA384: |
760 | case PWM_HASH_SHA512: | 802 | case PWM_HASH_SHA512: |
761 | case PWM_HASH_MD5: | 803 | case PWM_HASH_MD5: |
762 | case PWM_HASH_RMD160: | 804 | case PWM_HASH_RMD160: |
763 | case PWM_HASH_TIGER: { | 805 | case PWM_HASH_TIGER: { |
764 | if (!LibGCryptIf::available()) | 806 | if (!LibGCryptIf::available()) |
765 | return e_hashNotImpl; | 807 | return e_hashNotImpl; |
766 | LibGCryptIf gc; | 808 | LibGCryptIf gc; |
767 | PwMerror err; | 809 | PwMerror err; |
768 | unsigned char *buf; | 810 | unsigned char *buf; |
769 | size_t hashLen; | 811 | size_t hashLen; |
770 | err = gc.hash(&buf, | 812 | err = gc.hash(&buf, |
771 | &hashLen, | 813 | &hashLen, |
772 | reinterpret_cast<const unsigned char *>(pw->latin1()), | 814 | reinterpret_cast<const unsigned char *>(pw->latin1()), |
773 | pw->length(), | 815 | pw->length(), |
774 | keyHash); | 816 | keyHash); |
775 | if (err != e_success) | 817 | if (err != e_success) |
776 | return e_hashNotImpl; | 818 | return e_hashNotImpl; |
777 | string calcHash(reinterpret_cast<const char *>(buf), | 819 | string calcHash(reinterpret_cast<const char *>(buf), |
778 | static_cast<string::size_type>(hashLen)); | 820 | static_cast<string::size_type>(hashLen)); |
779 | delete [] buf; | 821 | delete [] buf; |
780 | // read hash from header | 822 | // read hash from header |
781 | string readHash; | 823 | string readHash; |
782 | size_t i; | 824 | size_t i; |
783 | for (i = 0; i < hashLen; ++i) | 825 | for (i = 0; i < hashLen; ++i) |
784 | readHash.push_back(f->getch()); | 826 | readHash.push_back(f->getch()); |
785 | if (calcHash != readHash) | 827 | if (calcHash != readHash) |
786 | return e_wrongPw;// hash doesn't match (wrong key) | 828 | return e_wrongPw;// hash doesn't match (wrong key) |
787 | break; | 829 | break; |
788 | } | 830 | } |
789 | default: { | 831 | default: { |
790 | return e_hashNotImpl; | 832 | return e_hashNotImpl; |
791 | } } | 833 | } } |
792 | // read the data-hash from the file | 834 | // read the data-hash from the file |
793 | unsigned int hashLen, i; | 835 | unsigned int hashLen, i; |
794 | switch (*dataHashType) { | 836 | switch (*dataHashType) { |
795 | case PWM_HASH_SHA1: | 837 | case PWM_HASH_SHA1: |
796 | hashLen = SHA1_HASH_LEN_BYTE; | 838 | hashLen = SHA1_HASH_LEN_BYTE; |
797 | break; | 839 | break; |
798 | case PWM_HASH_SHA256: | 840 | case PWM_HASH_SHA256: |
799 | /*... fall through */ | 841 | /*... fall through */ |
800 | case PWM_HASH_SHA384: | 842 | case PWM_HASH_SHA384: |
801 | case PWM_HASH_SHA512: | 843 | case PWM_HASH_SHA512: |
802 | case PWM_HASH_MD5: | 844 | case PWM_HASH_MD5: |
803 | case PWM_HASH_RMD160: | 845 | case PWM_HASH_RMD160: |
804 | case PWM_HASH_TIGER: { | 846 | case PWM_HASH_TIGER: { |
805 | if (!LibGCryptIf::available()) | 847 | if (!LibGCryptIf::available()) |
806 | return e_hashNotImpl; | 848 | return e_hashNotImpl; |
807 | LibGCryptIf gc; | 849 | LibGCryptIf gc; |
808 | hashLen = gc.hashLength(*dataHashType); | 850 | hashLen = gc.hashLength(*dataHashType); |
809 | if (hashLen == 0) | 851 | if (hashLen == 0) |
810 | return e_hashNotImpl; | 852 | return e_hashNotImpl; |
811 | break; | 853 | break; |
812 | } | 854 | } |
813 | default: | 855 | default: |
814 | return e_hashNotImpl; | 856 | return e_hashNotImpl; |
815 | } | 857 | } |
816 | *dataHash = ""; | 858 | *dataHash = ""; |
817 | for (i = 0; i < hashLen; ++i) { | 859 | for (i = 0; i < hashLen; ++i) { |
818 | tmpRet = f->getch(); | 860 | tmpRet = f->getch(); |
819 | if (tmpRet == -1) | 861 | if (tmpRet == -1) |
820 | return e_fileFormat; | 862 | return e_fileFormat; |
821 | dataHash->push_back(static_cast<char>(tmpRet)); | 863 | dataHash->push_back(static_cast<char>(tmpRet)); |
822 | } | 864 | } |
823 | *headerLength = f->at(); | 865 | *headerLength = f->at(); |
824 | #ifndef PWM_EMBEDDED | 866 | #ifndef PWM_EMBEDDED |
825 | printDebug(string("opening file { compress: ") | 867 | printDebug(string("opening file { compress: ") |
826 | + tostr(static_cast<int>(*compress)) + " cryptAlgo: " | 868 | + tostr(static_cast<int>(*compress)) + " cryptAlgo: " |
827 | + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " | 869 | + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " |
828 | + tostr(static_cast<int>(keyHash)) | 870 | + tostr(static_cast<int>(keyHash)) |
829 | + " }"); | 871 | + " }"); |
830 | #else | 872 | #else |
831 | printDebug(string("opening file { compress: ") | 873 | printDebug(string("opening file { compress: ") |
832 | + tostr((int)(*compress)) + " cryptAlgo: " | 874 | + tostr((int)(*compress)) + " cryptAlgo: " |
833 | + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " | 875 | + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " |
834 | + tostr((int)(keyHash)) | 876 | + tostr((int)(keyHash)) |
835 | + " }"); | 877 | + " }"); |
836 | #endif | 878 | #endif |
837 | 879 | ||
838 | return e_success; | 880 | return e_success; |
839 | } | 881 | } |
840 | 882 | ||
841 | PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) | 883 | PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) |
842 | { | 884 | { |
843 | PWM_ASSERT(d); | 885 | PWM_ASSERT(d); |
844 | PWM_ASSERT(f); | 886 | PWM_ASSERT(f); |
845 | 887 | ||
846 | switch (dataHash) { | 888 | switch (dataHash) { |
847 | case PWM_HASH_SHA1: { | 889 | case PWM_HASH_SHA1: { |
848 | const int hashLen = SHA1_HASH_LEN_BYTE; | 890 | const int hashLen = SHA1_HASH_LEN_BYTE; |
849 | Sha1 h; | 891 | Sha1 h; |
850 | h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); | 892 | h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); |
851 | string hRet = h.sha1_read(); | 893 | string hRet = h.sha1_read(); |
852 | if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) | 894 | if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) |
853 | return e_writeFile; | 895 | return e_writeFile; |
854 | break; | 896 | break; |
855 | } | 897 | } |
856 | case PWM_HASH_SHA256: | 898 | case PWM_HASH_SHA256: |
857 | /*... fall through */ | 899 | /*... fall through */ |
858 | case PWM_HASH_SHA384: | 900 | case PWM_HASH_SHA384: |
859 | case PWM_HASH_SHA512: | 901 | case PWM_HASH_SHA512: |
860 | case PWM_HASH_MD5: | 902 | case PWM_HASH_MD5: |
861 | case PWM_HASH_RMD160: | 903 | case PWM_HASH_RMD160: |
862 | case PWM_HASH_TIGER: { | 904 | case PWM_HASH_TIGER: { |
863 | if (!LibGCryptIf::available()) | 905 | if (!LibGCryptIf::available()) |
864 | return e_hashNotImpl; | 906 | return e_hashNotImpl; |
865 | LibGCryptIf gc; | 907 | LibGCryptIf gc; |
866 | PwMerror err; | 908 | PwMerror err; |
867 | unsigned char *buf; | 909 | unsigned char *buf; |
868 | size_t hashLen; | 910 | size_t hashLen; |
869 | err = gc.hash(&buf, | 911 | err = gc.hash(&buf, |
870 | &hashLen, | 912 | &hashLen, |
871 | reinterpret_cast<const unsigned char *>(d->c_str()), | 913 | reinterpret_cast<const unsigned char *>(d->c_str()), |
872 | d->size(), | 914 | d->size(), |
873 | dataHash); | 915 | dataHash); |
874 | if (err != e_success) | 916 | if (err != e_success) |
875 | return e_hashNotImpl; | 917 | return e_hashNotImpl; |
876 | if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) | 918 | if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) |
877 | != static_cast<Q_LONG>(hashLen)) { | 919 | != static_cast<Q_LONG>(hashLen)) { |
878 | delete [] buf; | 920 | delete [] buf; |
879 | return e_hashNotImpl; | 921 | return e_hashNotImpl; |
880 | } | 922 | } |
881 | delete [] buf; | 923 | delete [] buf; |
882 | break; | 924 | break; |
883 | } | 925 | } |
884 | default: { | 926 | default: { |
885 | return e_hashNotImpl; | 927 | return e_hashNotImpl; |
886 | } } | 928 | } } |
887 | 929 | ||
888 | return e_success; | 930 | return e_success; |
889 | } | 931 | } |
890 | 932 | ||
891 | bool PwMDoc::backupFile(const QString &filePath) | 933 | bool PwMDoc::backupFile(const QString &filePath) |
892 | { | 934 | { |
893 | QFileInfo fi(filePath); | 935 | QFileInfo fi(filePath); |
894 | if (!fi.exists()) | 936 | if (!fi.exists()) |
895 | return true; // Yes, true is correct. | 937 | return true; // Yes, true is correct. |
896 | QString pathOnly(fi.dirPath(true)); | 938 | QString pathOnly(fi.dirPath(true)); |
897 | QString nameOnly(fi.fileName()); | 939 | QString nameOnly(fi.fileName()); |
898 | QString backupPath = pathOnly | 940 | QString backupPath = pathOnly |
899 | + "/~" | 941 | + "/~" |
900 | + nameOnly | 942 | + nameOnly |
901 | + ".backup"; | 943 | + ".backup"; |
902 | return copyFile(filePath, backupPath); | 944 | return copyFile(filePath, backupPath); |
903 | } | 945 | } |
904 | 946 | ||
905 | bool PwMDoc::copyFile(const QString &src, const QString &dst) | 947 | bool PwMDoc::copyFile(const QString &src, const QString &dst) |
906 | { | 948 | { |
907 | QFileInfo fi(src); | 949 | QFileInfo fi(src); |
908 | if (!fi.exists()) | 950 | if (!fi.exists()) |
909 | return false; | 951 | return false; |
910 | if (QFile::exists(dst)) { | 952 | if (QFile::exists(dst)) { |
911 | if (!QFile::remove(dst)) | 953 | if (!QFile::remove(dst)) |
912 | return false; | 954 | return false; |
913 | } | 955 | } |
914 | QFile srcFd(src); | 956 | QFile srcFd(src); |
915 | if (!srcFd.open(IO_ReadOnly)) | 957 | if (!srcFd.open(IO_ReadOnly)) |
916 | return false; | 958 | return false; |
917 | QFile dstFd(dst); | 959 | QFile dstFd(dst); |
918 | if (!dstFd.open(IO_ReadWrite)) { | 960 | if (!dstFd.open(IO_ReadWrite)) { |
919 | srcFd.close(); | 961 | srcFd.close(); |
920 | return false; | 962 | return false; |
921 | } | 963 | } |
922 | const int tmpBuf_size = 512; | 964 | const int tmpBuf_size = 512; |
923 | char tmpBuf[tmpBuf_size]; | 965 | char tmpBuf[tmpBuf_size]; |
924 | Q_LONG bytesRead, bytesWritten; | 966 | Q_LONG bytesRead, bytesWritten; |
925 | 967 | ||
926 | while (!srcFd.atEnd()) { | 968 | while (!srcFd.atEnd()) { |
927 | bytesRead = srcFd.readBlock(tmpBuf, | 969 | bytesRead = srcFd.readBlock(tmpBuf, |
928 | static_cast<Q_ULONG>(tmpBuf_size)); | 970 | static_cast<Q_ULONG>(tmpBuf_size)); |
929 | if (bytesRead == -1) { | 971 | if (bytesRead == -1) { |
930 | srcFd.close(); | 972 | srcFd.close(); |
931 | dstFd.close(); | 973 | dstFd.close(); |
932 | return false; | 974 | return false; |
933 | } | 975 | } |
934 | bytesWritten = dstFd.writeBlock(tmpBuf, | 976 | bytesWritten = dstFd.writeBlock(tmpBuf, |
935 | static_cast<Q_ULONG>(bytesRead)); | 977 | static_cast<Q_ULONG>(bytesRead)); |
936 | if (bytesWritten != bytesRead) { | 978 | if (bytesWritten != bytesRead) { |
937 | srcFd.close(); | 979 | srcFd.close(); |
938 | dstFd.close(); | 980 | dstFd.close(); |
939 | return false; | 981 | return false; |
940 | } | 982 | } |
941 | } | 983 | } |
942 | srcFd.close(); | 984 | srcFd.close(); |
943 | dstFd.close(); | 985 | dstFd.close(); |
944 | return true; | 986 | return true; |
945 | } | 987 | } |
946 | 988 | ||
947 | PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, | 989 | PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, |
948 | bool dontFlagDirty, bool updateMeta) | 990 | bool dontFlagDirty, bool updateMeta) |
949 | { | 991 | { |
950 | PWM_ASSERT(d); | 992 | PWM_ASSERT(d); |
951 | unsigned int cat = 0; | 993 | unsigned int cat = 0; |
952 | 994 | ||
953 | if (isDeepLocked()) { | 995 | if (isDeepLocked()) { |
954 | PwMerror ret; | 996 | PwMerror ret; |
955 | ret = deepLock(false); | 997 | ret = deepLock(false); |
956 | if (ret != e_success) | 998 | if (ret != e_success) |
957 | return e_lock; | 999 | return e_lock; |
958 | } | 1000 | } |
959 | 1001 | ||
960 | addCategory(category, &cat); | 1002 | addCategory(category, &cat); |
961 | 1003 | ||
962 | if (numEntries(category) >= maxEntries) | 1004 | if (numEntries(category) >= maxEntries) |
963 | return e_maxAllowedEntr; | 1005 | return e_maxAllowedEntr; |
964 | 1006 | ||
965 | vector<unsigned int> foundPositions; | 1007 | vector<unsigned int> foundPositions; |
966 | /* historically this was: | 1008 | /* historically this was: |
967 | *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | | 1009 | *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | |
968 | * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; | 1010 | * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; |
969 | * But for now we only search in desc. | 1011 | * But for now we only search in desc. |
970 | * That's a tweak to be KWallet compatible. But it should not add | 1012 | * That's a tweak to be KWallet compatible. But it should not add |
971 | * usability-drop onto PwManager, does it? | 1013 | * usability-drop onto PwManager, does it? |
972 | * (And yes, "int" was a bug. Correct is "unsigned int") | 1014 | * (And yes, "int" was a bug. Correct is "unsigned int") |
973 | */ | 1015 | */ |
974 | const unsigned int searchIn = SEARCH_IN_DESC; | 1016 | const unsigned int searchIn = SEARCH_IN_DESC; |
975 | findEntry(cat, *d, searchIn, &foundPositions, true); | 1017 | findEntry(cat, *d, searchIn, &foundPositions, true); |
976 | if (foundPositions.size()) { | 1018 | if (foundPositions.size()) { |
977 | // DOH! We found this entry. | 1019 | // DOH! We found this entry. |
978 | return e_entryExists; | 1020 | return e_entryExists; |
979 | } | 1021 | } |
980 | 1022 | ||
981 | d->listViewPos = -1; | 1023 | d->listViewPos = -1; |
982 | d->lockStat = conf()->confGlobNewEntrLockStat(); | 1024 | d->lockStat = conf()->confGlobNewEntrLockStat(); |
983 | if (updateMeta) { | 1025 | if (updateMeta) { |
984 | d->meta.create = QDateTime::currentDateTime(); | 1026 | d->meta.create = QDateTime::currentDateTime(); |
985 | d->meta.update = d->meta.create; | 1027 | d->meta.update = d->meta.create; |
986 | } | 1028 | } |
987 | dti.dta[cat].d.push_back(*d); | 1029 | dti.dta[cat].d.push_back(*d); |
988 | 1030 | ||
989 | delAllEmptyCat(true); | 1031 | delAllEmptyCat(true); |
990 | 1032 | ||
991 | if (!dontFlagDirty) | 1033 | if (!dontFlagDirty) |
992 | flagDirty(); | 1034 | flagDirty(); |
@@ -1260,1024 +1302,1027 @@ PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo) | |||
1260 | PWM_ASSERT(f); | 1302 | PWM_ASSERT(f); |
1261 | 1303 | ||
1262 | size_t encSize; | 1304 | size_t encSize; |
1263 | byte *encrypted = 0; | 1305 | byte *encrypted = 0; |
1264 | 1306 | ||
1265 | switch (algo) { | 1307 | switch (algo) { |
1266 | case PWM_CRYPT_BLOWFISH: { | 1308 | case PWM_CRYPT_BLOWFISH: { |
1267 | Blowfish::padNull(d); | 1309 | Blowfish::padNull(d); |
1268 | encSize = d->length(); | 1310 | encSize = d->length(); |
1269 | encrypted = new byte[encSize]; | 1311 | encrypted = new byte[encSize]; |
1270 | Blowfish bf; | 1312 | Blowfish bf; |
1271 | if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { | 1313 | if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { |
1272 | delete [] encrypted; | 1314 | delete [] encrypted; |
1273 | return e_weakPw; | 1315 | return e_weakPw; |
1274 | } | 1316 | } |
1275 | bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); | 1317 | bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); |
1276 | break; | 1318 | break; |
1277 | } | 1319 | } |
1278 | case PWM_CRYPT_AES128: | 1320 | case PWM_CRYPT_AES128: |
1279 | /*... fall through */ | 1321 | /*... fall through */ |
1280 | case PWM_CRYPT_AES192: | 1322 | case PWM_CRYPT_AES192: |
1281 | case PWM_CRYPT_AES256: | 1323 | case PWM_CRYPT_AES256: |
1282 | case PWM_CRYPT_3DES: | 1324 | case PWM_CRYPT_3DES: |
1283 | case PWM_CRYPT_TWOFISH: | 1325 | case PWM_CRYPT_TWOFISH: |
1284 | case PWM_CRYPT_TWOFISH128: { | 1326 | case PWM_CRYPT_TWOFISH128: { |
1285 | if (!LibGCryptIf::available()) | 1327 | if (!LibGCryptIf::available()) |
1286 | return e_cryptNotImpl; | 1328 | return e_cryptNotImpl; |
1287 | LibGCryptIf gc; | 1329 | LibGCryptIf gc; |
1288 | PwMerror err; | 1330 | PwMerror err; |
1289 | unsigned char *plain = new unsigned char[d->length() + 1024]; | 1331 | unsigned char *plain = new unsigned char[d->length() + 1024]; |
1290 | memcpy(plain, d->c_str(), d->length()); | 1332 | memcpy(plain, d->c_str(), d->length()); |
1291 | err = gc.encrypt(&encrypted, | 1333 | err = gc.encrypt(&encrypted, |
1292 | &encSize, | 1334 | &encSize, |
1293 | plain, | 1335 | plain, |
1294 | d->length(), | 1336 | d->length(), |
1295 | reinterpret_cast<const unsigned char *>(pw->latin1()), | 1337 | reinterpret_cast<const unsigned char *>(pw->latin1()), |
1296 | pw->length(), | 1338 | pw->length(), |
1297 | algo); | 1339 | algo); |
1298 | delete [] plain; | 1340 | delete [] plain; |
1299 | if (err != e_success) | 1341 | if (err != e_success) |
1300 | return e_cryptNotImpl; | 1342 | return e_cryptNotImpl; |
1301 | break; | 1343 | break; |
1302 | } | 1344 | } |
1303 | default: { | 1345 | default: { |
1304 | delete_ifnot_null_array(encrypted); | 1346 | delete_ifnot_null_array(encrypted); |
1305 | return e_cryptNotImpl; | 1347 | return e_cryptNotImpl; |
1306 | } } | 1348 | } } |
1307 | 1349 | ||
1308 | // write encrypted data to file | 1350 | // write encrypted data to file |
1309 | if (f->writeBlock(reinterpret_cast<const char *>(encrypted), | 1351 | if (f->writeBlock(reinterpret_cast<const char *>(encrypted), |
1310 | static_cast<Q_ULONG>(encSize)) | 1352 | static_cast<Q_ULONG>(encSize)) |
1311 | != static_cast<Q_LONG>(encSize)) { | 1353 | != static_cast<Q_LONG>(encSize)) { |
1312 | delete_ifnot_null_array(encrypted); | 1354 | delete_ifnot_null_array(encrypted); |
1313 | return e_writeFile; | 1355 | return e_writeFile; |
1314 | } | 1356 | } |
1315 | delete_ifnot_null_array(encrypted); | 1357 | delete_ifnot_null_array(encrypted); |
1316 | return e_success; | 1358 | return e_success; |
1317 | } | 1359 | } |
1318 | 1360 | ||
1319 | PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, | 1361 | PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, |
1320 | char algo, QFile *f) | 1362 | char algo, QFile *f) |
1321 | { | 1363 | { |
1322 | PWM_ASSERT(d); | 1364 | PWM_ASSERT(d); |
1323 | PWM_ASSERT(pw); | 1365 | PWM_ASSERT(pw); |
1324 | PWM_ASSERT(f); | 1366 | PWM_ASSERT(f); |
1325 | 1367 | ||
1326 | unsigned int cryptLen = f->size() - pos; | 1368 | unsigned int cryptLen = f->size() - pos; |
1327 | byte *encrypted = new byte[cryptLen]; | 1369 | byte *encrypted = new byte[cryptLen]; |
1328 | byte *decrypted = new byte[cryptLen]; | 1370 | byte *decrypted = new byte[cryptLen]; |
1329 | 1371 | ||
1330 | f->at(pos); | 1372 | f->at(pos); |
1331 | #ifndef PWM_EMBEDDED | 1373 | #ifndef PWM_EMBEDDED |
1332 | if (f->readBlock(reinterpret_cast<char *>(encrypted), | 1374 | if (f->readBlock(reinterpret_cast<char *>(encrypted), |
1333 | static_cast<Q_ULONG>(cryptLen)) | 1375 | static_cast<Q_ULONG>(cryptLen)) |
1334 | != static_cast<Q_LONG>(cryptLen)) { | 1376 | != static_cast<Q_LONG>(cryptLen)) { |
1335 | delete [] encrypted; | 1377 | delete [] encrypted; |
1336 | delete [] decrypted; | 1378 | delete [] decrypted; |
1337 | return e_readFile; | 1379 | return e_readFile; |
1338 | } | 1380 | } |
1339 | #else | 1381 | #else |
1340 | if (f->readBlock((char *)(encrypted), | 1382 | if (f->readBlock((char *)(encrypted), |
1341 | (unsigned long)(cryptLen)) | 1383 | (unsigned long)(cryptLen)) |
1342 | != (long)(cryptLen)) { | 1384 | != (long)(cryptLen)) { |
1343 | delete [] encrypted; | 1385 | delete [] encrypted; |
1344 | delete [] decrypted; | 1386 | delete [] decrypted; |
1345 | return e_readFile; | 1387 | return e_readFile; |
1346 | } | 1388 | } |
1347 | #endif | 1389 | #endif |
1348 | switch (algo) { | 1390 | switch (algo) { |
1349 | case PWM_CRYPT_BLOWFISH: { | 1391 | case PWM_CRYPT_BLOWFISH: { |
1350 | Blowfish bf; | 1392 | Blowfish bf; |
1351 | bf.bf_setkey((byte *) pw->latin1(), pw->length()); | 1393 | bf.bf_setkey((byte *) pw->latin1(), pw->length()); |
1352 | bf.bf_decrypt(decrypted, encrypted, cryptLen); | 1394 | bf.bf_decrypt(decrypted, encrypted, cryptLen); |
1353 | break; | 1395 | break; |
1354 | } | 1396 | } |
1355 | case PWM_CRYPT_AES128: | 1397 | case PWM_CRYPT_AES128: |
1356 | /*... fall through */ | 1398 | /*... fall through */ |
1357 | case PWM_CRYPT_AES192: | 1399 | case PWM_CRYPT_AES192: |
1358 | case PWM_CRYPT_AES256: | 1400 | case PWM_CRYPT_AES256: |
1359 | case PWM_CRYPT_3DES: | 1401 | case PWM_CRYPT_3DES: |
1360 | case PWM_CRYPT_TWOFISH: | 1402 | case PWM_CRYPT_TWOFISH: |
1361 | case PWM_CRYPT_TWOFISH128: { | 1403 | case PWM_CRYPT_TWOFISH128: { |
1362 | if (!LibGCryptIf::available()) | 1404 | if (!LibGCryptIf::available()) |
1363 | return e_cryptNotImpl; | 1405 | return e_cryptNotImpl; |
1364 | LibGCryptIf gc; | 1406 | LibGCryptIf gc; |
1365 | PwMerror err; | 1407 | PwMerror err; |
1366 | err = gc.decrypt(&decrypted, | 1408 | err = gc.decrypt(&decrypted, |
1367 | &cryptLen, | 1409 | &cryptLen, |
1368 | encrypted, | 1410 | encrypted, |
1369 | cryptLen, | 1411 | cryptLen, |
1370 | reinterpret_cast<const unsigned char *>(pw->latin1()), | 1412 | reinterpret_cast<const unsigned char *>(pw->latin1()), |
1371 | pw->length(), | 1413 | pw->length(), |
1372 | algo); | 1414 | algo); |
1373 | if (err != e_success) { | 1415 | if (err != e_success) { |
1374 | delete [] encrypted; | 1416 | delete [] encrypted; |
1375 | delete [] decrypted; | 1417 | delete [] decrypted; |
1376 | return e_cryptNotImpl; | 1418 | return e_cryptNotImpl; |
1377 | } | 1419 | } |
1378 | break; | 1420 | break; |
1379 | } | 1421 | } |
1380 | default: { | 1422 | default: { |
1381 | delete [] encrypted; | 1423 | delete [] encrypted; |
1382 | delete [] decrypted; | 1424 | delete [] decrypted; |
1383 | return e_cryptNotImpl; | 1425 | return e_cryptNotImpl; |
1384 | } } | 1426 | } } |
1385 | delete [] encrypted; | 1427 | delete [] encrypted; |
1386 | #ifndef PWM_EMBEDDED | 1428 | #ifndef PWM_EMBEDDED |
1387 | d->assign(reinterpret_cast<const char *>(decrypted), | 1429 | d->assign(reinterpret_cast<const char *>(decrypted), |
1388 | static_cast<string::size_type>(cryptLen)); | 1430 | static_cast<string::size_type>(cryptLen)); |
1389 | #else | 1431 | #else |
1390 | d->assign((const char *)(decrypted), | 1432 | d->assign((const char *)(decrypted), |
1391 | (string::size_type)(cryptLen)); | 1433 | (string::size_type)(cryptLen)); |
1392 | #endif | 1434 | #endif |
1393 | delete [] decrypted; | 1435 | delete [] decrypted; |
1394 | if (algo == PWM_CRYPT_BLOWFISH) { | 1436 | if (algo == PWM_CRYPT_BLOWFISH) { |
1395 | if (!Blowfish::unpadNull(d)) { | 1437 | if (!Blowfish::unpadNull(d)) { |
1396 | BUG(); | 1438 | BUG(); |
1397 | return e_readFile; | 1439 | return e_readFile; |
1398 | } | 1440 | } |
1399 | } | 1441 | } |
1400 | return e_success; | 1442 | return e_success; |
1401 | } | 1443 | } |
1402 | 1444 | ||
1403 | PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, | 1445 | PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, |
1404 | const string *dataStream) | 1446 | const string *dataStream) |
1405 | { | 1447 | { |
1406 | PWM_ASSERT(dataHash); | 1448 | PWM_ASSERT(dataHash); |
1407 | PWM_ASSERT(dataStream); | 1449 | PWM_ASSERT(dataStream); |
1408 | switch(dataHashType) { | 1450 | switch(dataHashType) { |
1409 | case PWM_HASH_SHA1: { | 1451 | case PWM_HASH_SHA1: { |
1410 | Sha1 hash; | 1452 | Sha1 hash; |
1411 | hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); | 1453 | hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); |
1412 | string ret = hash.sha1_read(); | 1454 | string ret = hash.sha1_read(); |
1413 | if (ret != *dataHash) | 1455 | if (ret != *dataHash) |
1414 | return e_fileCorrupt; | 1456 | return e_fileCorrupt; |
1415 | break; | 1457 | break; |
1416 | } | 1458 | } |
1417 | case PWM_HASH_SHA256: | 1459 | case PWM_HASH_SHA256: |
1418 | /*... fall through */ | 1460 | /*... fall through */ |
1419 | case PWM_HASH_SHA384: | 1461 | case PWM_HASH_SHA384: |
1420 | case PWM_HASH_SHA512: | 1462 | case PWM_HASH_SHA512: |
1421 | case PWM_HASH_MD5: | 1463 | case PWM_HASH_MD5: |
1422 | case PWM_HASH_RMD160: | 1464 | case PWM_HASH_RMD160: |
1423 | case PWM_HASH_TIGER: { | 1465 | case PWM_HASH_TIGER: { |
1424 | if (!LibGCryptIf::available()) | 1466 | if (!LibGCryptIf::available()) |
1425 | return e_hashNotImpl; | 1467 | return e_hashNotImpl; |
1426 | LibGCryptIf gc; | 1468 | LibGCryptIf gc; |
1427 | PwMerror err; | 1469 | PwMerror err; |
1428 | unsigned char *buf; | 1470 | unsigned char *buf; |
1429 | size_t hashLen; | 1471 | size_t hashLen; |
1430 | err = gc.hash(&buf, | 1472 | err = gc.hash(&buf, |
1431 | &hashLen, | 1473 | &hashLen, |
1432 | reinterpret_cast<const unsigned char *>(dataStream->c_str()), | 1474 | reinterpret_cast<const unsigned char *>(dataStream->c_str()), |
1433 | dataStream->length(), | 1475 | dataStream->length(), |
1434 | dataHashType); | 1476 | dataHashType); |
1435 | if (err != e_success) | 1477 | if (err != e_success) |
1436 | return e_hashNotImpl; | 1478 | return e_hashNotImpl; |
1437 | string calcHash(reinterpret_cast<const char *>(buf), | 1479 | string calcHash(reinterpret_cast<const char *>(buf), |
1438 | static_cast<string::size_type>(hashLen)); | 1480 | static_cast<string::size_type>(hashLen)); |
1439 | delete [] buf; | 1481 | delete [] buf; |
1440 | if (calcHash != *dataHash) | 1482 | if (calcHash != *dataHash) |
1441 | return e_fileCorrupt; | 1483 | return e_fileCorrupt; |
1442 | break; | 1484 | break; |
1443 | } | 1485 | } |
1444 | default: | 1486 | default: |
1445 | return e_hashNotImpl; | 1487 | return e_hashNotImpl; |
1446 | } | 1488 | } |
1447 | return e_success; | 1489 | return e_success; |
1448 | } | 1490 | } |
1449 | 1491 | ||
1450 | bool PwMDoc::lockAt(unsigned int category, unsigned int index, | 1492 | bool PwMDoc::lockAt(unsigned int category, unsigned int index, |
1451 | bool lock) | 1493 | bool lock) |
1452 | { | 1494 | { |
1453 | if (index >= numEntries(category)) { | 1495 | if (index >= numEntries(category)) { |
1454 | BUG(); | 1496 | BUG(); |
1455 | return false; | 1497 | return false; |
1456 | } | 1498 | } |
1457 | if (lock == dti.dta[category].d[index].lockStat) | 1499 | if (lock == dti.dta[category].d[index].lockStat) |
1458 | return true; | 1500 | return true; |
1459 | 1501 | ||
1460 | if (!lock && currentPw != "") { | 1502 | if (!lock && currentPw != "") { |
1461 | // "unlocking" and "password is already set" | 1503 | // "unlocking" and "password is already set" |
1462 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { | 1504 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { |
1463 | // unlocking without pw not allowed | 1505 | // unlocking without pw not allowed |
1464 | QString pw; | 1506 | QString pw; |
1465 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1507 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1466 | if (pw != "") { | 1508 | if (pw != "") { |
1467 | if (pw != currentPw) { | 1509 | if (pw != currentPw) { |
1468 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1510 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1469 | return false; | 1511 | return false; |
1470 | } else { | 1512 | } else { |
1471 | timer()->start(DocTimer::id_mpwTimer); | 1513 | timer()->start(DocTimer::id_mpwTimer); |
1472 | } | 1514 | } |
1473 | } else { | 1515 | } else { |
1474 | return false; | 1516 | return false; |
1475 | } | 1517 | } |
1476 | } else { | 1518 | } else { |
1477 | timer()->start(DocTimer::id_mpwTimer); | 1519 | timer()->start(DocTimer::id_mpwTimer); |
1478 | } | 1520 | } |
1479 | } | 1521 | } |
1480 | 1522 | ||
1481 | dti.dta[category].d[index].lockStat = lock; | 1523 | dti.dta[category].d[index].lockStat = lock; |
1482 | dti.dta[category].d[index].rev++; // increment revision counter. | 1524 | dti.dta[category].d[index].rev++; // increment revision counter. |
1483 | 1525 | ||
1484 | emitDataChanged(this); | 1526 | emitDataChanged(this); |
1485 | if (!lock) | 1527 | if (!lock) |
1486 | timer()->start(DocTimer::id_autoLockTimer); | 1528 | timer()->start(DocTimer::id_autoLockTimer); |
1487 | 1529 | ||
1488 | return true; | 1530 | return true; |
1489 | 1531 | ||
1490 | } | 1532 | } |
1491 | 1533 | ||
1492 | bool PwMDoc::lockAt(const QString &category,unsigned int index, | 1534 | bool PwMDoc::lockAt(const QString &category,unsigned int index, |
1493 | bool lock) | 1535 | bool lock) |
1494 | { | 1536 | { |
1495 | unsigned int cat = 0; | 1537 | unsigned int cat = 0; |
1496 | 1538 | ||
1497 | if (!findCategory(category, &cat)) { | 1539 | if (!findCategory(category, &cat)) { |
1498 | BUG(); | 1540 | BUG(); |
1499 | return false; | 1541 | return false; |
1500 | } | 1542 | } |
1501 | 1543 | ||
1502 | return lockAt(cat, index, lock); | 1544 | return lockAt(cat, index, lock); |
1503 | } | 1545 | } |
1504 | 1546 | ||
1505 | bool PwMDoc::lockAll(bool lock) | 1547 | bool PwMDoc::lockAll(bool lock) |
1506 | { | 1548 | { |
1507 | if (!lock && isDeepLocked()) { | 1549 | if (!lock && isDeepLocked()) { |
1508 | PwMerror ret; | 1550 | PwMerror ret; |
1509 | ret = deepLock(false); | 1551 | ret = deepLock(false); |
1510 | if (ret != e_success) | 1552 | if (ret != e_success) |
1511 | return false; | 1553 | return false; |
1512 | return true; | 1554 | return true; |
1513 | } | 1555 | } |
1514 | if (isDocEmpty()) { | 1556 | if (isDocEmpty()) { |
1515 | return true; | 1557 | return true; |
1516 | } | 1558 | } |
1517 | if (!lock && currentPw != "") { | 1559 | if (!lock && currentPw != "") { |
1518 | // unlocking and password is already set | 1560 | // unlocking and password is already set |
1519 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { | 1561 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { |
1520 | // unlocking without pw not allowed | 1562 | // unlocking without pw not allowed |
1521 | QString pw; | 1563 | QString pw; |
1522 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1564 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1523 | if (pw != "") { | 1565 | if (pw != "") { |
1524 | if (pw != currentPw) { | 1566 | if (pw != currentPw) { |
1525 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1567 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1526 | return false; | 1568 | return false; |
1527 | } else { | 1569 | } else { |
1528 | timer()->start(DocTimer::id_mpwTimer); | 1570 | timer()->start(DocTimer::id_mpwTimer); |
1529 | } | 1571 | } |
1530 | } else { | 1572 | } else { |
1531 | return false; | 1573 | return false; |
1532 | } | 1574 | } |
1533 | } else { | 1575 | } else { |
1534 | timer()->start(DocTimer::id_mpwTimer); | 1576 | timer()->start(DocTimer::id_mpwTimer); |
1535 | } | 1577 | } |
1536 | } | 1578 | } |
1537 | 1579 | ||
1538 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), | 1580 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), |
1539 | catEnd = dti.dta.end(), | 1581 | catEnd = dti.dta.end(), |
1540 | catI = catBegin; | 1582 | catI = catBegin; |
1541 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; | 1583 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; |
1542 | while (catI != catEnd) { | 1584 | while (catI != catEnd) { |
1543 | entrBegin = catI->d.begin(); | 1585 | entrBegin = catI->d.begin(); |
1544 | entrEnd = catI->d.end(); | 1586 | entrEnd = catI->d.end(); |
1545 | entrI = entrBegin; | 1587 | entrI = entrBegin; |
1546 | while (entrI != entrEnd) { | 1588 | while (entrI != entrEnd) { |
1547 | entrI->lockStat = lock; | 1589 | entrI->lockStat = lock; |
1548 | entrI->rev++; // increment revision counter. | 1590 | entrI->rev++; // increment revision counter. |
1549 | ++entrI; | 1591 | ++entrI; |
1550 | } | 1592 | } |
1551 | ++catI; | 1593 | ++catI; |
1552 | } | 1594 | } |
1553 | 1595 | ||
1554 | emitDataChanged(this); | 1596 | emitDataChanged(this); |
1555 | if (lock) | 1597 | if (lock) |
1556 | timer()->stop(DocTimer::id_autoLockTimer); | 1598 | timer()->stop(DocTimer::id_autoLockTimer); |
1557 | else | 1599 | else |
1558 | timer()->start(DocTimer::id_autoLockTimer); | 1600 | timer()->start(DocTimer::id_autoLockTimer); |
1559 | 1601 | ||
1560 | return true; | 1602 | return true; |
1561 | } | 1603 | } |
1562 | 1604 | ||
1563 | bool PwMDoc::isLocked(const QString &category, unsigned int index) | 1605 | bool PwMDoc::isLocked(const QString &category, unsigned int index) |
1564 | { | 1606 | { |
1565 | unsigned int cat = 0; | 1607 | unsigned int cat = 0; |
1566 | 1608 | ||
1567 | if (!findCategory(category, &cat)) { | 1609 | if (!findCategory(category, &cat)) { |
1568 | BUG(); | 1610 | BUG(); |
1569 | return false; | 1611 | return false; |
1570 | } | 1612 | } |
1571 | 1613 | ||
1572 | return isLocked(cat, index); | 1614 | return isLocked(cat, index); |
1573 | } | 1615 | } |
1574 | 1616 | ||
1575 | bool PwMDoc::unlockAll_tempoary(bool revert) | 1617 | bool PwMDoc::unlockAll_tempoary(bool revert) |
1576 | { | 1618 | { |
1577 | static vector< vector<bool> > *oldLockStates = 0; | 1619 | static vector< vector<bool> > *oldLockStates = 0; |
1578 | static bool wasDeepLocked; | 1620 | static bool wasDeepLocked; |
1579 | 1621 | ||
1580 | if (revert) {// revert the unlocking | 1622 | if (revert) {// revert the unlocking |
1581 | if (oldLockStates) { | 1623 | if (oldLockStates) { |
1582 | /* we actually _have_ unlocked something, because | 1624 | /* we actually _have_ unlocked something, because |
1583 | * we have allocated space for the oldLockStates. | 1625 | * we have allocated space for the oldLockStates. |
1584 | * So, go on and revert them! | 1626 | * So, go on and revert them! |
1585 | */ | 1627 | */ |
1586 | if (wasDeepLocked) { | 1628 | if (wasDeepLocked) { |
1587 | PwMerror ret = deepLock(true); | 1629 | PwMerror ret = deepLock(true); |
1588 | if (ret == e_success) { | 1630 | if (ret == e_success) { |
1589 | /* deep-lock succeed. We are save. | 1631 | /* deep-lock succeed. We are save. |
1590 | * (but if it failed, just go on | 1632 | * (but if it failed, just go on |
1591 | * lock them normally) | 1633 | * lock them normally) |
1592 | */ | 1634 | */ |
1593 | delete_and_null(oldLockStates); | 1635 | delete_and_null(oldLockStates); |
1594 | timer()->start(DocTimer::id_autoLockTimer); | 1636 | timer()->start(DocTimer::id_autoLockTimer); |
1595 | printDebug("tempoary unlocking of dta " | 1637 | printDebug("tempoary unlocking of dta " |
1596 | "reverted by deep-locking."); | 1638 | "reverted by deep-locking."); |
1597 | return true; | 1639 | return true; |
1598 | } | 1640 | } |
1599 | printDebug("deep-lock failed while reverting! " | 1641 | printDebug("deep-lock failed while reverting! " |
1600 | "Falling back to normal-lock."); | 1642 | "Falling back to normal-lock."); |
1601 | } | 1643 | } |
1602 | if (unlikely(!wasDeepLocked && | 1644 | if (unlikely(!wasDeepLocked && |
1603 | numCategories() != oldLockStates->size())) { | 1645 | numCategories() != oldLockStates->size())) { |
1604 | /* DOH! We have modified "dta" while | 1646 | /* DOH! We have modified "dta" while |
1605 | * it was unlocked tempoary. DON'T DO THIS! | 1647 | * it was unlocked tempoary. DON'T DO THIS! |
1606 | */ | 1648 | */ |
1607 | BUG(); | 1649 | BUG(); |
1608 | delete_and_null(oldLockStates); | 1650 | delete_and_null(oldLockStates); |
1609 | timer()->start(DocTimer::id_autoLockTimer); | 1651 | timer()->start(DocTimer::id_autoLockTimer); |
1610 | return false; | 1652 | return false; |
1611 | } | 1653 | } |
1612 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), | 1654 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), |
1613 | catEnd = dti.dta.end(), | 1655 | catEnd = dti.dta.end(), |
1614 | catI = catBegin; | 1656 | catI = catBegin; |
1615 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; | 1657 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; |
1616 | vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); | 1658 | vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); |
1617 | vector<bool>::iterator oldEntrStatBegin, | 1659 | vector<bool>::iterator oldEntrStatBegin, |
1618 | oldEntrStatEnd, | 1660 | oldEntrStatEnd, |
1619 | oldEntrStatI; | 1661 | oldEntrStatI; |
1620 | while (catI != catEnd) { | 1662 | while (catI != catEnd) { |
1621 | entrBegin = catI->d.begin(); | 1663 | entrBegin = catI->d.begin(); |
1622 | entrEnd = catI->d.end(); | 1664 | entrEnd = catI->d.end(); |
1623 | entrI = entrBegin; | 1665 | entrI = entrBegin; |
1624 | if (likely(!wasDeepLocked)) { | 1666 | if (likely(!wasDeepLocked)) { |
1625 | oldEntrStatBegin = oldCatStatI->begin(); | 1667 | oldEntrStatBegin = oldCatStatI->begin(); |
1626 | oldEntrStatEnd = oldCatStatI->end(); | 1668 | oldEntrStatEnd = oldCatStatI->end(); |
1627 | oldEntrStatI = oldEntrStatBegin; | 1669 | oldEntrStatI = oldEntrStatBegin; |
1628 | if (unlikely(catI->d.size() != oldCatStatI->size())) { | 1670 | if (unlikely(catI->d.size() != oldCatStatI->size())) { |
1629 | /* DOH! We have modified "dta" while | 1671 | /* DOH! We have modified "dta" while |
1630 | * it was unlocked tempoary. DON'T DO THIS! | 1672 | * it was unlocked tempoary. DON'T DO THIS! |
1631 | */ | 1673 | */ |
1632 | BUG(); | 1674 | BUG(); |
1633 | delete_and_null(oldLockStates); | 1675 | delete_and_null(oldLockStates); |
1634 | timer()->start(DocTimer::id_autoLockTimer); | 1676 | timer()->start(DocTimer::id_autoLockTimer); |
1635 | return false; | 1677 | return false; |
1636 | } | 1678 | } |
1637 | } | 1679 | } |
1638 | while (entrI != entrEnd) { | 1680 | while (entrI != entrEnd) { |
1639 | if (wasDeepLocked) { | 1681 | if (wasDeepLocked) { |
1640 | /* this is an error-fallback if | 1682 | /* this is an error-fallback if |
1641 | * deeplock didn't succeed | 1683 | * deeplock didn't succeed |
1642 | */ | 1684 | */ |
1643 | entrI->lockStat = true; | 1685 | entrI->lockStat = true; |
1644 | } else { | 1686 | } else { |
1645 | entrI->lockStat = *oldEntrStatI; | 1687 | entrI->lockStat = *oldEntrStatI; |
1646 | } | 1688 | } |
1647 | ++entrI; | 1689 | ++entrI; |
1648 | if (likely(!wasDeepLocked)) | 1690 | if (likely(!wasDeepLocked)) |
1649 | ++oldEntrStatI; | 1691 | ++oldEntrStatI; |
1650 | } | 1692 | } |
1651 | ++catI; | 1693 | ++catI; |
1652 | if (likely(!wasDeepLocked)) | 1694 | if (likely(!wasDeepLocked)) |
1653 | ++oldCatStatI; | 1695 | ++oldCatStatI; |
1654 | } | 1696 | } |
1655 | delete_and_null(oldLockStates); | 1697 | delete_and_null(oldLockStates); |
1656 | if (unlikely(wasDeepLocked)) { | 1698 | if (unlikely(wasDeepLocked)) { |
1657 | /* error fallback... */ | 1699 | /* error fallback... */ |
1658 | unsetDocStatFlag(DOC_STAT_DEEPLOCKED); | 1700 | unsetDocStatFlag(DOC_STAT_DEEPLOCKED); |
1659 | emitDataChanged(this); | 1701 | emitDataChanged(this); |
1660 | printDebug("WARNING: unlockAll_tempoary(true) " | 1702 | printDebug("WARNING: unlockAll_tempoary(true) " |
1661 | "deeplock fallback!"); | 1703 | "deeplock fallback!"); |
1662 | } | 1704 | } |
1663 | printDebug("tempoary unlocking of dta reverted."); | 1705 | printDebug("tempoary unlocking of dta reverted."); |
1664 | } else { | 1706 | } else { |
1665 | printDebug("unlockAll_tempoary(true): nothing to do."); | 1707 | printDebug("unlockAll_tempoary(true): nothing to do."); |
1666 | } | 1708 | } |
1667 | timer()->start(DocTimer::id_autoLockTimer); | 1709 | timer()->start(DocTimer::id_autoLockTimer); |
1668 | } else {// unlock all data tempoary | 1710 | } else {// unlock all data tempoary |
1669 | if (unlikely(oldLockStates != 0)) { | 1711 | if (unlikely(oldLockStates != 0)) { |
1670 | /* DOH! We have already unlocked the data tempoarly. | 1712 | /* DOH! We have already unlocked the data tempoarly. |
1671 | * No need to do it twice. ;) | 1713 | * No need to do it twice. ;) |
1672 | */ | 1714 | */ |
1673 | BUG(); | 1715 | BUG(); |
1674 | return false; | 1716 | return false; |
1675 | } | 1717 | } |
1676 | wasDeepLocked = false; | 1718 | wasDeepLocked = false; |
1677 | bool mustUnlock = false; | 1719 | bool mustUnlock = false; |
1678 | if (isDeepLocked()) { | 1720 | if (isDeepLocked()) { |
1679 | PwMerror ret; | 1721 | PwMerror ret; |
1680 | while (1) { | 1722 | while (1) { |
1681 | ret = deepLock(false); | 1723 | ret = deepLock(false); |
1682 | if (ret == e_success) { | 1724 | if (ret == e_success) { |
1683 | break; | 1725 | break; |
1684 | } else if (ret == e_wrongPw) { | 1726 | } else if (ret == e_wrongPw) { |
1685 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1727 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1686 | } else { | 1728 | } else { |
1687 | printDebug("deep-unlocking failed while " | 1729 | printDebug("deep-unlocking failed while " |
1688 | "tempoary unlocking!"); | 1730 | "tempoary unlocking!"); |
1689 | return false; | 1731 | return false; |
1690 | } | 1732 | } |
1691 | } | 1733 | } |
1692 | wasDeepLocked = true; | 1734 | wasDeepLocked = true; |
1693 | mustUnlock = true; | 1735 | mustUnlock = true; |
1694 | } else { | 1736 | } else { |
1695 | // first check if it's needed to unlock some entries | 1737 | // first check if it's needed to unlock some entries |
1696 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), | 1738 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), |
1697 | catEnd = dti.dta.end(), | 1739 | catEnd = dti.dta.end(), |
1698 | catI = catBegin; | 1740 | catI = catBegin; |
1699 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; | 1741 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; |
1700 | while (catI != catEnd) { | 1742 | while (catI != catEnd) { |
1701 | entrBegin = catI->d.begin(); | 1743 | entrBegin = catI->d.begin(); |
1702 | entrEnd = catI->d.end(); | 1744 | entrEnd = catI->d.end(); |
1703 | entrI = entrBegin; | 1745 | entrI = entrBegin; |
1704 | while (entrI != entrEnd) { | 1746 | while (entrI != entrEnd) { |
1705 | if (entrI->lockStat == true) { | 1747 | if (entrI->lockStat == true) { |
1706 | mustUnlock = true; | 1748 | mustUnlock = true; |
1707 | break; | 1749 | break; |
1708 | } | 1750 | } |
1709 | ++entrI; | 1751 | ++entrI; |
1710 | } | 1752 | } |
1711 | if (mustUnlock) | 1753 | if (mustUnlock) |
1712 | break; | 1754 | break; |
1713 | ++catI; | 1755 | ++catI; |
1714 | } | 1756 | } |
1715 | } | 1757 | } |
1716 | if (!mustUnlock) { | 1758 | if (!mustUnlock) { |
1717 | // nothing to do. | 1759 | // nothing to do. |
1718 | timer()->stop(DocTimer::id_autoLockTimer); | 1760 | timer()->stop(DocTimer::id_autoLockTimer); |
1719 | printDebug("unlockAll_tempoary(): nothing to do."); | 1761 | printDebug("unlockAll_tempoary(): nothing to do."); |
1720 | return true; | 1762 | return true; |
1721 | } else if (!wasDeepLocked) { | 1763 | } else if (!wasDeepLocked) { |
1722 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && | 1764 | if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && |
1723 | currentPw != "") { | 1765 | currentPw != "") { |
1724 | /* we can't unlock without mpw, so | 1766 | /* we can't unlock without mpw, so |
1725 | * we need to ask for it. | 1767 | * we need to ask for it. |
1726 | */ | 1768 | */ |
1727 | QString pw; | 1769 | QString pw; |
1728 | while (1) { | 1770 | while (1) { |
1729 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1771 | pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1730 | if (pw == "") { | 1772 | if (pw == "") { |
1731 | return false; | 1773 | return false; |
1732 | } else if (pw == currentPw) { | 1774 | } else if (pw == currentPw) { |
1733 | break; | 1775 | break; |
1734 | } | 1776 | } |
1735 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); | 1777 | wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); |
1736 | } | 1778 | } |
1737 | } | 1779 | } |
1738 | } | 1780 | } |
1739 | timer()->stop(DocTimer::id_autoLockTimer); | 1781 | timer()->stop(DocTimer::id_autoLockTimer); |
1740 | oldLockStates = new vector< vector<bool> >; | 1782 | oldLockStates = new vector< vector<bool> >; |
1741 | vector<bool> tmp_vec; | 1783 | vector<bool> tmp_vec; |
1742 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), | 1784 | vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), |
1743 | catEnd = dti.dta.end(), | 1785 | catEnd = dti.dta.end(), |
1744 | catI = catBegin; | 1786 | catI = catBegin; |
1745 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; | 1787 | vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; |
1746 | while (catI != catEnd) { | 1788 | while (catI != catEnd) { |
1747 | entrBegin = catI->d.begin(); | 1789 | entrBegin = catI->d.begin(); |
1748 | entrEnd = catI->d.end(); | 1790 | entrEnd = catI->d.end(); |
1749 | entrI = entrBegin; | 1791 | entrI = entrBegin; |
1750 | while (entrI != entrEnd) { | 1792 | while (entrI != entrEnd) { |
1751 | if (!wasDeepLocked) { | 1793 | if (!wasDeepLocked) { |
1752 | tmp_vec.push_back(entrI->lockStat); | 1794 | tmp_vec.push_back(entrI->lockStat); |
1753 | } | 1795 | } |
1754 | entrI->lockStat = false; | 1796 | entrI->lockStat = false; |
1755 | ++entrI; | 1797 | ++entrI; |
1756 | } | 1798 | } |
1757 | if (!wasDeepLocked) { | 1799 | if (!wasDeepLocked) { |
1758 | oldLockStates->push_back(tmp_vec); | 1800 | oldLockStates->push_back(tmp_vec); |
1759 | tmp_vec.clear(); | 1801 | tmp_vec.clear(); |
1760 | } | 1802 | } |
1761 | ++catI; | 1803 | ++catI; |
1762 | } | 1804 | } |
1763 | printDebug("tempoary unlocked dta."); | 1805 | printDebug("tempoary unlocked dta."); |
1764 | } | 1806 | } |
1765 | 1807 | ||
1766 | return true; | 1808 | return true; |
1767 | } | 1809 | } |
1768 | 1810 | ||
1769 | PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) | 1811 | PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) |
1770 | { | 1812 | { |
1771 | PwMerror ret; | 1813 | PwMerror ret; |
1814 | /* NOTE: saveDoc() depends on this function to return | ||
1815 | * e_success if saveToFile == false | ||
1816 | */ | ||
1772 | 1817 | ||
1773 | if (lock) { | 1818 | if (lock) { |
1774 | if (isDeepLocked()) | 1819 | if (isDeepLocked()) |
1775 | return e_lock; | 1820 | return e_lock; |
1776 | if (saveToFile) { | 1821 | if (saveToFile) { |
1777 | if (isDocEmpty()) | 1822 | if (isDocEmpty()) |
1778 | return e_docIsEmpty; | 1823 | return e_docIsEmpty; |
1779 | ret = saveDoc(conf()->confGlobCompression()); | 1824 | ret = saveDoc(conf()->confGlobCompression()); |
1780 | if (ret == e_filename) { | 1825 | if (ret == e_filename) { |
1781 | /* the doc wasn't saved to a file | 1826 | /* the doc wasn't saved to a file |
1782 | * by the user, yet. | 1827 | * by the user, yet. |
1783 | */ | 1828 | */ |
1784 | cantDeeplock_notSavedMsgBox(); | 1829 | cantDeeplock_notSavedMsgBox(); |
1785 | return e_docNotSaved; | 1830 | return e_docNotSaved; |
1786 | } else if (ret != e_success) { | 1831 | } else if (ret != e_success) { |
1787 | return e_lock; | 1832 | return e_lock; |
1788 | } | 1833 | } |
1789 | } | 1834 | } |
1790 | timer()->stop(DocTimer::id_autoLockTimer); | 1835 | timer()->stop(DocTimer::id_autoLockTimer); |
1791 | clearDoc(); | 1836 | clearDoc(); |
1792 | PwMDataItem d; | 1837 | PwMDataItem d; |
1793 | d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); | 1838 | d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); |
1794 | d.comment = IS_DEEPLOCKED_MSG.latin1(); | 1839 | d.comment = IS_DEEPLOCKED_MSG.latin1(); |
1795 | d.listViewPos = 0; | 1840 | d.listViewPos = 0; |
1796 | addEntry(DEFAULT_CATEGORY, &d, true); | 1841 | addEntry(DEFAULT_CATEGORY, &d, true); |
1797 | lockAt(DEFAULT_CATEGORY, 0, true); | 1842 | lockAt(DEFAULT_CATEGORY, 0, true); |
1798 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); | 1843 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); |
1799 | setDocStatFlag(DOC_STAT_DEEPLOCKED); | 1844 | setDocStatFlag(DOC_STAT_DEEPLOCKED); |
1800 | } else { | 1845 | } else { |
1801 | if (!isDeepLocked()) | 1846 | if (!isDeepLocked()) |
1802 | return e_lock; | 1847 | return e_lock; |
1803 | ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) | 1848 | ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) |
1804 | ? 0 : 1); | 1849 | ? 0 : 1); |
1805 | if (ret == e_wrongPw) { | 1850 | if (ret == e_wrongPw) { |
1806 | return e_wrongPw; | 1851 | return e_wrongPw; |
1807 | } else if (ret != e_success) { | 1852 | } else if (ret != e_success) { |
1808 | printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") | 1853 | printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") |
1809 | + tostr(static_cast<int>(ret))); | 1854 | + tostr(static_cast<int>(ret))); |
1810 | return e_lock; | 1855 | return e_lock; |
1811 | } | 1856 | } |
1812 | unsetDocStatFlag(DOC_STAT_DEEPLOCKED); | 1857 | unsetDocStatFlag(DOC_STAT_DEEPLOCKED); |
1813 | timer()->start(DocTimer::id_autoLockTimer); | 1858 | timer()->start(DocTimer::id_autoLockTimer); |
1814 | } | 1859 | } |
1815 | 1860 | ||
1816 | emitDataChanged(this); | 1861 | emitDataChanged(this); |
1817 | return e_success; | 1862 | return e_success; |
1818 | } | 1863 | } |
1819 | 1864 | ||
1820 | void PwMDoc::_deepUnlock() | 1865 | void PwMDoc::_deepUnlock() |
1821 | { | 1866 | { |
1822 | deepLock(false); | 1867 | deepLock(false); |
1823 | } | 1868 | } |
1824 | 1869 | ||
1825 | void PwMDoc::clearDoc() | 1870 | void PwMDoc::clearDoc() |
1826 | { | 1871 | { |
1827 | dti.clear(); | 1872 | dti.clear(); |
1828 | PwMCategoryItem d; | 1873 | PwMCategoryItem d; |
1829 | d.name = DEFAULT_CATEGORY.latin1(); | 1874 | d.name = DEFAULT_CATEGORY.latin1(); |
1830 | dti.dta.push_back(d); | 1875 | dti.dta.push_back(d); |
1831 | currentPw = ""; | 1876 | currentPw = ""; |
1832 | unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); | 1877 | unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); |
1833 | } | 1878 | } |
1834 | 1879 | ||
1835 | void PwMDoc::changeCurrentPw() | 1880 | void PwMDoc::changeCurrentPw() |
1836 | { | 1881 | { |
1837 | if (currentPw == "") | 1882 | if (currentPw == "") |
1838 | return; // doc hasn't been saved. No mpw available. | 1883 | return; // doc hasn't been saved. No mpw available. |
1839 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); | 1884 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); |
1840 | QString pw = requestMpwChange(¤tPw, &useChipcard); | 1885 | QString pw = requestMpwChange(¤tPw, &useChipcard); |
1841 | if (pw == "") | 1886 | if (pw == "") |
1842 | return; | 1887 | return; |
1843 | if (useChipcard) | 1888 | if (useChipcard) |
1844 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); | 1889 | setDocStatFlag(DOC_STAT_USE_CHIPCARD); |
1845 | else | 1890 | else |
1846 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); | 1891 | unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); |
1847 | setCurrentPw(pw); | 1892 | setCurrentPw(pw); |
1848 | } | 1893 | } |
1849 | 1894 | ||
1850 | void PwMDoc::setListViewPos(const QString &category, unsigned int index, | 1895 | void PwMDoc::setListViewPos(const QString &category, unsigned int index, |
1851 | int pos) | 1896 | int pos) |
1852 | { | 1897 | { |
1853 | unsigned int cat = 0; | 1898 | unsigned int cat = 0; |
1854 | 1899 | ||
1855 | if (!findCategory(category, &cat)) { | 1900 | if (!findCategory(category, &cat)) { |
1856 | BUG(); | 1901 | BUG(); |
1857 | return; | 1902 | return; |
1858 | } | 1903 | } |
1859 | setListViewPos(cat, index, pos); | 1904 | setListViewPos(cat, index, pos); |
1860 | } | 1905 | } |
1861 | 1906 | ||
1862 | void PwMDoc::setListViewPos(unsigned int category, unsigned int index, | 1907 | void PwMDoc::setListViewPos(unsigned int category, unsigned int index, |
1863 | int pos) | 1908 | int pos) |
1864 | { | 1909 | { |
1865 | dti.dta[category].d[index].listViewPos = pos; | 1910 | dti.dta[category].d[index].listViewPos = pos; |
1866 | 1911 | ||
1867 | /* FIXME workaround: don't flag dirty, because this function sometimes | 1912 | /* FIXME workaround: don't flag dirty, because this function sometimes |
1868 | * get's called when it shouldn't. It's because PwMView assumes | 1913 | * get's called when it shouldn't. It's because PwMView assumes |
1869 | * the user resorted the UI on behalf of signal layoutChanged(). | 1914 | * the user resorted the UI on behalf of signal layoutChanged(). |
1870 | * This is somewhat broken and incorrect, but I've no other | 1915 | * This is somewhat broken and incorrect, but I've no other |
1871 | * solution for now. | 1916 | * solution for now. |
1872 | */ | 1917 | */ |
1873 | //setDocStatFlag(DOC_STAT_DISK_DIRTY); | 1918 | //setDocStatFlag(DOC_STAT_DISK_DIRTY); |
1874 | } | 1919 | } |
1875 | 1920 | ||
1876 | int PwMDoc::getListViewPos(const QString &category, unsigned int index) | 1921 | int PwMDoc::getListViewPos(const QString &category, unsigned int index) |
1877 | { | 1922 | { |
1878 | unsigned int cat = 0; | 1923 | unsigned int cat = 0; |
1879 | 1924 | ||
1880 | if (!findCategory(category, &cat)) { | 1925 | if (!findCategory(category, &cat)) { |
1881 | BUG(); | 1926 | BUG(); |
1882 | return -1; | 1927 | return -1; |
1883 | } | 1928 | } |
1884 | 1929 | ||
1885 | return dti.dta[cat].d[index].listViewPos; | 1930 | return dti.dta[cat].d[index].listViewPos; |
1886 | } | 1931 | } |
1887 | 1932 | ||
1888 | void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, | 1933 | void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, |
1889 | vector<unsigned int> *foundPositions, bool breakAfterFound, | 1934 | vector<unsigned int> *foundPositions, bool breakAfterFound, |
1890 | bool caseSensitive, bool exactWordMatch, bool sortByLvp) | 1935 | bool caseSensitive, bool exactWordMatch, bool sortByLvp) |
1891 | { | 1936 | { |
1892 | PWM_ASSERT(foundPositions); | 1937 | PWM_ASSERT(foundPositions); |
1893 | PWM_ASSERT(searchIn); | 1938 | PWM_ASSERT(searchIn); |
1894 | foundPositions->clear(); | 1939 | foundPositions->clear(); |
1895 | 1940 | ||
1896 | unsigned int i, entries = numEntries(category); | 1941 | unsigned int i, entries = numEntries(category); |
1897 | for (i = 0; i < entries; ++i) { | 1942 | for (i = 0; i < entries; ++i) { |
1898 | if (searchIn & SEARCH_IN_DESC) { | 1943 | if (searchIn & SEARCH_IN_DESC) { |
1899 | if (!compareString(find.desc, dti.dta[category].d[i].desc, | 1944 | if (!compareString(find.desc, dti.dta[category].d[i].desc, |
1900 | caseSensitive, exactWordMatch)) { | 1945 | caseSensitive, exactWordMatch)) { |
1901 | continue; | 1946 | continue; |
1902 | } | 1947 | } |
1903 | } | 1948 | } |
1904 | if (searchIn & SEARCH_IN_NAME) { | 1949 | if (searchIn & SEARCH_IN_NAME) { |
1905 | if (!compareString(find.name, dti.dta[category].d[i].name, | 1950 | if (!compareString(find.name, dti.dta[category].d[i].name, |
1906 | caseSensitive, exactWordMatch)) { | 1951 | caseSensitive, exactWordMatch)) { |
1907 | continue; | 1952 | continue; |
1908 | } | 1953 | } |
1909 | } | 1954 | } |
1910 | if (searchIn & SEARCH_IN_PW) { | 1955 | if (searchIn & SEARCH_IN_PW) { |
1911 | bool wasLocked = isLocked(category, i); | 1956 | bool wasLocked = isLocked(category, i); |
1912 | getDataChangedLock(); | 1957 | getDataChangedLock(); |
1913 | lockAt(category, i, false); | 1958 | lockAt(category, i, false); |
1914 | if (!compareString(find.pw, dti.dta[category].d[i].pw, | 1959 | if (!compareString(find.pw, dti.dta[category].d[i].pw, |
1915 | caseSensitive, exactWordMatch)) { | 1960 | caseSensitive, exactWordMatch)) { |
1916 | lockAt(category, i, wasLocked); | 1961 | lockAt(category, i, wasLocked); |
1917 | putDataChangedLock(); | 1962 | putDataChangedLock(); |
1918 | continue; | 1963 | continue; |
1919 | } | 1964 | } |
1920 | lockAt(category, i, wasLocked); | 1965 | lockAt(category, i, wasLocked); |
1921 | putDataChangedLock(); | 1966 | putDataChangedLock(); |
1922 | } | 1967 | } |
1923 | if (searchIn & SEARCH_IN_COMMENT) { | 1968 | if (searchIn & SEARCH_IN_COMMENT) { |
1924 | if (!compareString(find.comment, dti.dta[category].d[i].comment, | 1969 | if (!compareString(find.comment, dti.dta[category].d[i].comment, |
1925 | caseSensitive, exactWordMatch)) { | 1970 | caseSensitive, exactWordMatch)) { |
1926 | continue; | 1971 | continue; |
1927 | } | 1972 | } |
1928 | } | 1973 | } |
1929 | if (searchIn & SEARCH_IN_URL) { | 1974 | if (searchIn & SEARCH_IN_URL) { |
1930 | if (!compareString(find.url, dti.dta[category].d[i].url, | 1975 | if (!compareString(find.url, dti.dta[category].d[i].url, |
1931 | caseSensitive, exactWordMatch)) { | 1976 | caseSensitive, exactWordMatch)) { |
1932 | continue; | 1977 | continue; |
1933 | } | 1978 | } |
1934 | } | 1979 | } |
1935 | if (searchIn & SEARCH_IN_LAUNCHER) { | 1980 | if (searchIn & SEARCH_IN_LAUNCHER) { |
1936 | if (!compareString(find.launcher, dti.dta[category].d[i].launcher, | 1981 | if (!compareString(find.launcher, dti.dta[category].d[i].launcher, |
1937 | caseSensitive, exactWordMatch)) { | 1982 | caseSensitive, exactWordMatch)) { |
1938 | continue; | 1983 | continue; |
1939 | } | 1984 | } |
1940 | } | 1985 | } |
1941 | 1986 | ||
1942 | // all selected "searchIn" matched. | 1987 | // all selected "searchIn" matched. |
1943 | foundPositions->push_back(i); | 1988 | foundPositions->push_back(i); |
1944 | if (breakAfterFound) | 1989 | if (breakAfterFound) |
1945 | break; | 1990 | break; |
1946 | } | 1991 | } |
1947 | 1992 | ||
1948 | if (sortByLvp && foundPositions->size() > 1) { | 1993 | if (sortByLvp && foundPositions->size() > 1) { |
1949 | vector< pair<unsigned int /* foundPosition (real doc pos) */, | 1994 | vector< pair<unsigned int /* foundPosition (real doc pos) */, |
1950 | unsigned int /* lvp-pos */> > tmp_vec; | 1995 | unsigned int /* lvp-pos */> > tmp_vec; |
1951 | 1996 | ||
1952 | unsigned int i, items = foundPositions->size(); | 1997 | unsigned int i, items = foundPositions->size(); |
1953 | pair<unsigned int, unsigned int> tmp_pair; | 1998 | pair<unsigned int, unsigned int> tmp_pair; |
1954 | for (i = 0; i < items; ++i) { | 1999 | for (i = 0; i < items; ++i) { |
1955 | tmp_pair.first = (*foundPositions)[i]; | 2000 | tmp_pair.first = (*foundPositions)[i]; |
1956 | tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; | 2001 | tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; |
1957 | tmp_vec.push_back(tmp_pair); | 2002 | tmp_vec.push_back(tmp_pair); |
1958 | } | 2003 | } |
1959 | sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); | 2004 | sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); |
1960 | foundPositions->clear(); | 2005 | foundPositions->clear(); |
1961 | for (i = 0; i < items; ++i) { | 2006 | for (i = 0; i < items; ++i) { |
1962 | foundPositions->push_back(tmp_vec[i].first); | 2007 | foundPositions->push_back(tmp_vec[i].first); |
1963 | } | 2008 | } |
1964 | } | 2009 | } |
1965 | } | 2010 | } |
1966 | 2011 | ||
1967 | void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, | 2012 | void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, |
1968 | vector<unsigned int> *foundPositions, bool breakAfterFound, | 2013 | vector<unsigned int> *foundPositions, bool breakAfterFound, |
1969 | bool caseSensitive, bool exactWordMatch, bool sortByLvp) | 2014 | bool caseSensitive, bool exactWordMatch, bool sortByLvp) |
1970 | { | 2015 | { |
1971 | PWM_ASSERT(foundPositions); | 2016 | PWM_ASSERT(foundPositions); |
1972 | unsigned int cat = 0; | 2017 | unsigned int cat = 0; |
1973 | 2018 | ||
1974 | if (!findCategory(category, &cat)) { | 2019 | if (!findCategory(category, &cat)) { |
1975 | foundPositions->clear(); | 2020 | foundPositions->clear(); |
1976 | return; | 2021 | return; |
1977 | } | 2022 | } |
1978 | 2023 | ||
1979 | findEntry(cat, find, searchIn, foundPositions, breakAfterFound, | 2024 | findEntry(cat, find, searchIn, foundPositions, breakAfterFound, |
1980 | caseSensitive, exactWordMatch, sortByLvp); | 2025 | caseSensitive, exactWordMatch, sortByLvp); |
1981 | } | 2026 | } |
1982 | 2027 | ||
1983 | bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, | 2028 | bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, |
1984 | bool exactWordMatch) | 2029 | bool exactWordMatch) |
1985 | { | 2030 | { |
1986 | QString _s1(s1.c_str()); | 2031 | QString _s1(s1.c_str()); |
1987 | QString _s2(s2.c_str()); | 2032 | QString _s2(s2.c_str()); |
1988 | if (!caseSensitive) { | 2033 | if (!caseSensitive) { |
1989 | _s1 = _s1.lower(); | 2034 | _s1 = _s1.lower(); |
1990 | _s2 = _s2.lower(); | 2035 | _s2 = _s2.lower(); |
1991 | } | 2036 | } |
1992 | if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) | 2037 | if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) |
1993 | return true; | 2038 | return true; |
1994 | return false; | 2039 | return false; |
1995 | } | 2040 | } |
1996 | 2041 | ||
1997 | bool PwMDoc::findCategory(const QString &name, unsigned int *index) | 2042 | bool PwMDoc::findCategory(const QString &name, unsigned int *index) |
1998 | { | 2043 | { |
1999 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), | 2044 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), |
2000 | end = dti.dta.end(); | 2045 | end = dti.dta.end(); |
2001 | while (i != end) { | 2046 | while (i != end) { |
2002 | if ((*i).name == name.latin1()) { | 2047 | if ((*i).name == name.latin1()) { |
2003 | if (index) { | 2048 | if (index) { |
2004 | *index = i - dti.dta.begin(); | 2049 | *index = i - dti.dta.begin(); |
2005 | } | 2050 | } |
2006 | return true; | 2051 | return true; |
2007 | } | 2052 | } |
2008 | ++i; | 2053 | ++i; |
2009 | } | 2054 | } |
2010 | return false; | 2055 | return false; |
2011 | } | 2056 | } |
2012 | 2057 | ||
2013 | bool PwMDoc::renameCategory(const QString &category, const QString &newName) | 2058 | bool PwMDoc::renameCategory(const QString &category, const QString &newName) |
2014 | { | 2059 | { |
2015 | unsigned int cat = 0; | 2060 | unsigned int cat = 0; |
2016 | 2061 | ||
2017 | if (!findCategory(category, &cat)) | 2062 | if (!findCategory(category, &cat)) |
2018 | return false; | 2063 | return false; |
2019 | 2064 | ||
2020 | return renameCategory(cat, newName); | 2065 | return renameCategory(cat, newName); |
2021 | } | 2066 | } |
2022 | 2067 | ||
2023 | bool PwMDoc::renameCategory(unsigned int category, const QString &newName, | 2068 | bool PwMDoc::renameCategory(unsigned int category, const QString &newName, |
2024 | bool dontFlagDirty) | 2069 | bool dontFlagDirty) |
2025 | { | 2070 | { |
2026 | if (category > numCategories() - 1) | 2071 | if (category > numCategories() - 1) |
2027 | return false; | 2072 | return false; |
2028 | 2073 | ||
2029 | dti.dta[category].name = newName.latin1(); | 2074 | dti.dta[category].name = newName.latin1(); |
2030 | if (!dontFlagDirty) | 2075 | if (!dontFlagDirty) |
2031 | flagDirty(); | 2076 | flagDirty(); |
2032 | 2077 | ||
2033 | return true; | 2078 | return true; |
2034 | } | 2079 | } |
2035 | 2080 | ||
2036 | bool PwMDoc::delCategory(const QString &category) | 2081 | bool PwMDoc::delCategory(const QString &category) |
2037 | { | 2082 | { |
2038 | unsigned int cat = 0; | 2083 | unsigned int cat = 0; |
2039 | 2084 | ||
2040 | if (!findCategory(category, &cat)) | 2085 | if (!findCategory(category, &cat)) |
2041 | return false; | 2086 | return false; |
2042 | 2087 | ||
2043 | return delCategory(cat); | 2088 | return delCategory(cat); |
2044 | } | 2089 | } |
2045 | 2090 | ||
2046 | bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) | 2091 | bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) |
2047 | { | 2092 | { |
2048 | if (category > numCategories() - 1) | 2093 | if (category > numCategories() - 1) |
2049 | return false; | 2094 | return false; |
2050 | 2095 | ||
2051 | // We don't delete it, if it is the last existing | 2096 | // We don't delete it, if it is the last existing |
2052 | // category! Instead we rename it to "Default". | 2097 | // category! Instead we rename it to "Default". |
2053 | if (numCategories() > 1) { | 2098 | if (numCategories() > 1) { |
2054 | dti.dta.erase(dti.dta.begin() + category); | 2099 | dti.dta.erase(dti.dta.begin() + category); |
2055 | } else { | 2100 | } else { |
2056 | renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); | 2101 | renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); |
2057 | return true; | 2102 | return true; |
2058 | } | 2103 | } |
2059 | if (!dontFlagDirty) | 2104 | if (!dontFlagDirty) |
2060 | flagDirty(); | 2105 | flagDirty(); |
2061 | 2106 | ||
2062 | return true; | 2107 | return true; |
2063 | } | 2108 | } |
2064 | 2109 | ||
2065 | void PwMDoc::delAllEmptyCat(bool dontFlagDirty) | 2110 | void PwMDoc::delAllEmptyCat(bool dontFlagDirty) |
2066 | { | 2111 | { |
2067 | vector<PwMCategoryItem>::iterator begin = dti.dta.begin(), | 2112 | vector<PwMCategoryItem>::iterator begin = dti.dta.begin(), |
2068 | end = dti.dta.end(), | 2113 | end = dti.dta.end(), |
2069 | i = begin; | 2114 | i = begin; |
2070 | while (i != end) { | 2115 | while (i != end) { |
2071 | if (i->d.empty()) { | 2116 | if (i->d.empty()) { |
2072 | delCategory(begin - i, dontFlagDirty); | 2117 | delCategory(begin - i, dontFlagDirty); |
2073 | } | 2118 | } |
2074 | ++i; | 2119 | ++i; |
2075 | } | 2120 | } |
2076 | } | 2121 | } |
2077 | 2122 | ||
2078 | void PwMDoc::getCategoryList(vector<string> *list) | 2123 | void PwMDoc::getCategoryList(vector<string> *list) |
2079 | { | 2124 | { |
2080 | PWM_ASSERT(list); | 2125 | PWM_ASSERT(list); |
2081 | list->clear(); | 2126 | list->clear(); |
2082 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), | 2127 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), |
2083 | end = dti.dta.end(); | 2128 | end = dti.dta.end(); |
2084 | while (i != end) { | 2129 | while (i != end) { |
2085 | list->push_back(i->name); | 2130 | list->push_back(i->name); |
2086 | ++i; | 2131 | ++i; |
2087 | } | 2132 | } |
2088 | } | 2133 | } |
2089 | 2134 | ||
2090 | void PwMDoc::getCategoryList(QStringList *list) | 2135 | void PwMDoc::getCategoryList(QStringList *list) |
2091 | { | 2136 | { |
2092 | PWM_ASSERT(list); | 2137 | PWM_ASSERT(list); |
2093 | list->clear(); | 2138 | list->clear(); |
2094 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), | 2139 | vector<PwMCategoryItem>::iterator i = dti.dta.begin(), |
2095 | end = dti.dta.end(); | 2140 | end = dti.dta.end(); |
2096 | while (i != end) { | 2141 | while (i != end) { |
2097 | #ifndef PWM_EMBEDDED | 2142 | #ifndef PWM_EMBEDDED |
2098 | list->push_back(i->name.c_str()); | 2143 | list->push_back(i->name.c_str()); |
2099 | #else | 2144 | #else |
2100 | list->append(i->name.c_str()); | 2145 | list->append(i->name.c_str()); |
2101 | #endif | 2146 | #endif |
2102 | ++i; | 2147 | ++i; |
2103 | } | 2148 | } |
2104 | } | 2149 | } |
2105 | 2150 | ||
2106 | void PwMDoc::getEntryList(const QString &category, QStringList *list) | 2151 | void PwMDoc::getEntryList(const QString &category, QStringList *list) |
2107 | { | 2152 | { |
2108 | PWM_ASSERT(list); | 2153 | PWM_ASSERT(list); |
2109 | unsigned int cat = 0; | 2154 | unsigned int cat = 0; |
2110 | if (!findCategory(category, &cat)) { | 2155 | if (!findCategory(category, &cat)) { |
2111 | list->clear(); | 2156 | list->clear(); |
2112 | return; | 2157 | return; |
2113 | } | 2158 | } |
2114 | getEntryList(cat, list); | 2159 | getEntryList(cat, list); |
2115 | } | 2160 | } |
2116 | 2161 | ||
2117 | void PwMDoc::getEntryList(const QString &category, vector<string> *list) | 2162 | void PwMDoc::getEntryList(const QString &category, vector<string> *list) |
2118 | { | 2163 | { |
2119 | PWM_ASSERT(list); | 2164 | PWM_ASSERT(list); |
2120 | unsigned int cat = 0; | 2165 | unsigned int cat = 0; |
2121 | if (!findCategory(category, &cat)) { | 2166 | if (!findCategory(category, &cat)) { |
2122 | list->clear(); | 2167 | list->clear(); |
2123 | return; | 2168 | return; |
2124 | } | 2169 | } |
2125 | getEntryList(cat, list); | 2170 | getEntryList(cat, list); |
2126 | } | 2171 | } |
2127 | 2172 | ||
2128 | void PwMDoc::getEntryList(unsigned int category, vector<string> *list) | 2173 | void PwMDoc::getEntryList(unsigned int category, vector<string> *list) |
2129 | { | 2174 | { |
2130 | PWM_ASSERT(list); | 2175 | PWM_ASSERT(list); |
2131 | list->clear(); | 2176 | list->clear(); |
2132 | vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), | 2177 | vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), |
2133 | end = dti.dta[category].d.end(), | 2178 | end = dti.dta[category].d.end(), |
2134 | i = begin; | 2179 | i = begin; |
2135 | while (i != end) { | 2180 | while (i != end) { |
2136 | list->push_back(i->desc); | 2181 | list->push_back(i->desc); |
2137 | ++i; | 2182 | ++i; |
2138 | } | 2183 | } |
2139 | } | 2184 | } |
2140 | 2185 | ||
2141 | void PwMDoc::getEntryList(unsigned int category, QStringList *list) | 2186 | void PwMDoc::getEntryList(unsigned int category, QStringList *list) |
2142 | { | 2187 | { |
2143 | PWM_ASSERT(list); | 2188 | PWM_ASSERT(list); |
2144 | list->clear(); | 2189 | list->clear(); |
2145 | vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), | 2190 | vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), |
2146 | end = dti.dta[category].d.end(), | 2191 | end = dti.dta[category].d.end(), |
2147 | i = begin; | 2192 | i = begin; |
2148 | while (i != end) { | 2193 | while (i != end) { |
2149 | #ifndef PWM_EMBEDDED | 2194 | #ifndef PWM_EMBEDDED |
2150 | list->push_back(i->desc.c_str()); | 2195 | list->push_back(i->desc.c_str()); |
2151 | #else | 2196 | #else |
2152 | list->append(i->desc.c_str()); | 2197 | list->append(i->desc.c_str()); |
2153 | #endif | 2198 | #endif |
2154 | ++i; | 2199 | ++i; |
2155 | } | 2200 | } |
2156 | } | 2201 | } |
2157 | 2202 | ||
2158 | bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex) | 2203 | bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex) |
2159 | { | 2204 | { |
2160 | unsigned int cat = 0; | 2205 | unsigned int cat = 0; |
2161 | 2206 | ||
2162 | if (!findCategory(category, &cat)) | 2207 | if (!findCategory(category, &cat)) |
2163 | return false; | 2208 | return false; |
2164 | 2209 | ||
2165 | return execLauncher(cat, entryIndex); | 2210 | return execLauncher(cat, entryIndex); |
2166 | } | 2211 | } |
2167 | 2212 | ||
2168 | bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex) | 2213 | bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex) |
2169 | { | 2214 | { |
2170 | if (geteuid() == 0) { | 2215 | if (geteuid() == 0) { |
2171 | rootAlertMsgBox(); | 2216 | rootAlertMsgBox(); |
2172 | return false; | 2217 | return false; |
2173 | } | 2218 | } |
2174 | QString command(dti.dta[category].d[entryIndex].launcher.c_str()); | 2219 | QString command(dti.dta[category].d[entryIndex].launcher.c_str()); |
2175 | bool wasLocked = isLocked(category, entryIndex); | 2220 | bool wasLocked = isLocked(category, entryIndex); |
2176 | 2221 | ||
2177 | if (command.find("$p") != -1) { | 2222 | if (command.find("$p") != -1) { |
2178 | /* the user requested the password to be included | 2223 | /* the user requested the password to be included |
2179 | * into the command. We have to ask for the password, | 2224 | * into the command. We have to ask for the password, |
2180 | * if it's locked. We do that by unlocking the entry | 2225 | * if it's locked. We do that by unlocking the entry |
2181 | */ | 2226 | */ |
2182 | if (!lockAt(category, entryIndex, false)) | 2227 | if (!lockAt(category, entryIndex, false)) |
2183 | return false; | 2228 | return false; |
2184 | } | 2229 | } |
2185 | #ifndef PWM_EMBEDDED | 2230 | #ifndef PWM_EMBEDDED |
2186 | command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str()); | 2231 | command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str()); |
2187 | command.replace("$n", dti.dta[category].d[entryIndex].name.c_str()); | 2232 | command.replace("$n", dti.dta[category].d[entryIndex].name.c_str()); |
2188 | command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str()); | 2233 | command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str()); |
2189 | command.replace("$u", dti.dta[category].d[entryIndex].url.c_str()); | 2234 | command.replace("$u", dti.dta[category].d[entryIndex].url.c_str()); |
2190 | command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str()); | 2235 | command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str()); |
2191 | #else | 2236 | #else |
2192 | command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str()); | 2237 | command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str()); |
2193 | command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str()); | 2238 | command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str()); |
2194 | command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str()); | 2239 | command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str()); |
2195 | command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str()); | 2240 | command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str()); |
2196 | command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str()); | 2241 | command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str()); |
2197 | #endif | 2242 | #endif |
2198 | command.append(" &"); | 2243 | command.append(" &"); |
2199 | 2244 | ||
2200 | QString customXterm(conf()->confGlobXtermCommand()); | 2245 | QString customXterm(conf()->confGlobXtermCommand()); |
2201 | if (!customXterm.isEmpty()) | 2246 | if (!customXterm.isEmpty()) |
2202 | command = customXterm + " " + command; | 2247 | command = customXterm + " " + command; |
2203 | 2248 | ||
2204 | system(command.latin1()); | 2249 | system(command.latin1()); |
2205 | 2250 | ||
2206 | lockAt(category, entryIndex, wasLocked); | 2251 | lockAt(category, entryIndex, wasLocked); |
2207 | return true; | 2252 | return true; |
2208 | } | 2253 | } |
2209 | 2254 | ||
2210 | bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex) | 2255 | bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex) |
2211 | { | 2256 | { |
2212 | unsigned int cat = 0; | 2257 | unsigned int cat = 0; |
2213 | 2258 | ||
2214 | if (!findCategory(category, &cat)) | 2259 | if (!findCategory(category, &cat)) |
2215 | return false; | 2260 | return false; |
2216 | 2261 | ||
2217 | return goToURL(cat, entryIndex); | 2262 | return goToURL(cat, entryIndex); |
2218 | } | 2263 | } |
2219 | 2264 | ||
2220 | bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex) | 2265 | bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex) |
2221 | { | 2266 | { |
2222 | if (geteuid() == 0) { | 2267 | if (geteuid() == 0) { |
2223 | rootAlertMsgBox(); | 2268 | rootAlertMsgBox(); |
2224 | return false; | 2269 | return false; |
2225 | } | 2270 | } |
2226 | QString url(dti.dta[category].d[entryIndex].url.c_str()); | 2271 | QString url(dti.dta[category].d[entryIndex].url.c_str()); |
2227 | if (url.isEmpty()) | 2272 | if (url.isEmpty()) |
2228 | return false; | 2273 | return false; |
2229 | 2274 | ||
2230 | QString customBrowser(conf()->confGlobBrowserCommand()); | 2275 | QString customBrowser(conf()->confGlobBrowserCommand()); |
2231 | if (!customBrowser.isEmpty()) { | 2276 | if (!customBrowser.isEmpty()) { |
2232 | browserProc.clearArguments(); | 2277 | browserProc.clearArguments(); |
2233 | browserProc << customBrowser << url; | 2278 | browserProc << customBrowser << url; |
2234 | if (browserProc.start(KProcess::DontCare)) | 2279 | if (browserProc.start(KProcess::DontCare)) |
2235 | return true; | 2280 | return true; |
2236 | } | 2281 | } |
2237 | 2282 | ||
2238 | browserProc.clearArguments(); | 2283 | browserProc.clearArguments(); |
2239 | browserProc << "konqueror" << url; | 2284 | browserProc << "konqueror" << url; |
2240 | if (browserProc.start(KProcess::DontCare)) | 2285 | if (browserProc.start(KProcess::DontCare)) |
2241 | return true; | 2286 | return true; |
2242 | 2287 | ||
2243 | browserProc.clearArguments(); | 2288 | browserProc.clearArguments(); |
2244 | browserProc << "mozilla" << url; | 2289 | browserProc << "mozilla" << url; |
2245 | if (browserProc.start(KProcess::DontCare)) | 2290 | if (browserProc.start(KProcess::DontCare)) |
2246 | return true; | 2291 | return true; |
2247 | 2292 | ||
2248 | browserProc.clearArguments(); | 2293 | browserProc.clearArguments(); |
2249 | browserProc << "opera" << url; | 2294 | browserProc << "opera" << url; |
2250 | if (browserProc.start(KProcess::DontCare)) | 2295 | if (browserProc.start(KProcess::DontCare)) |
2251 | return true; | 2296 | return true; |
2252 | return false; | 2297 | return false; |
2253 | } | 2298 | } |
2254 | 2299 | ||
2255 | PwMerror PwMDoc::exportToText(const QString *file) | 2300 | PwMerror PwMDoc::exportToText(const QString *file) |
2256 | { | 2301 | { |
2257 | PWM_ASSERT(file); | 2302 | PWM_ASSERT(file); |
2258 | if (QFile::exists(*file)) { | 2303 | if (QFile::exists(*file)) { |
2259 | if (!QFile::remove(*file)) | 2304 | if (!QFile::remove(*file)) |
2260 | return e_accessFile; | 2305 | return e_accessFile; |
2261 | } | 2306 | } |
2262 | QFile f(*file); | 2307 | QFile f(*file); |
2263 | if (!f.open(IO_ReadWrite)) | 2308 | if (!f.open(IO_ReadWrite)) |
2264 | return e_openFile; | 2309 | return e_openFile; |
2265 | 2310 | ||
2266 | if (!unlockAll_tempoary()) { | 2311 | if (!unlockAll_tempoary()) { |
2267 | f.close(); | 2312 | f.close(); |
2268 | return e_lock; | 2313 | return e_lock; |
2269 | } | 2314 | } |
2270 | 2315 | ||
2271 | // write header | 2316 | // write header |
2272 | string header = i18n("Password table generated by\nPwM v").latin1(); | 2317 | string header = i18n("Password table generated by\nPwM v").latin1(); |
2273 | header += PACKAGE_VER; | 2318 | header += PACKAGE_VER; |
2274 | header += i18n("\non ").latin1(); | 2319 | header += i18n("\non ").latin1(); |
2275 | QDate currDate = QDate::currentDate(); | 2320 | QDate currDate = QDate::currentDate(); |
2276 | QTime currTime = QTime::currentTime(); | 2321 | QTime currTime = QTime::currentTime(); |
2277 | 2322 | ||
2278 | #ifndef PWM_EMBEDDED | 2323 | #ifndef PWM_EMBEDDED |
2279 | header += currDate.toString("ddd MMMM d ").latin1(); | 2324 | header += currDate.toString("ddd MMMM d ").latin1(); |
2280 | header += currTime.toString("hh:mm:ss ").latin1(); | 2325 | header += currTime.toString("hh:mm:ss ").latin1(); |
2281 | #else | 2326 | #else |
2282 | QString dfs = KGlobal::locale()->dateFormatShort(); | 2327 | QString dfs = KGlobal::locale()->dateFormatShort(); |
2283 | bool ampm = KGlobal::locale()->use12Clock(); | 2328 | bool ampm = KGlobal::locale()->use12Clock(); |
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h index 535fb92..a6e5f58 100644 --- a/pwmanager/pwmanager/pwmdoc.h +++ b/pwmanager/pwmanager/pwmdoc.h | |||
@@ -1,526 +1,526 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * * | 2 | * * |
3 | * copyright (C) 2003, 2004 by Michael Buesch * | 3 | * copyright (C) 2003, 2004 by Michael Buesch * |
4 | * email: mbuesch@freenet.de * | 4 | * email: mbuesch@freenet.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License version 2 * | 7 | * it under the terms of the GNU General Public License version 2 * |
8 | * as published by the Free Software Foundation. * | 8 | * as published by the Free Software Foundation. * |
9 | * * | 9 | * * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | /*************************************************************************** | 12 | /*************************************************************************** |
13 | * copyright (C) 2004 by Ulf Schenk | 13 | * copyright (C) 2004 by Ulf Schenk |
14 | * This file is originaly based on version 2.0 of pwmanager | 14 | * This file is originaly based on version 1.1 of pwmanager |
15 | * and was modified to run on embedded devices that run microkde | 15 | * and was modified to run on embedded devices that run microkde |
16 | * | 16 | * |
17 | * $Id$ | 17 | * $Id$ |
18 | **************************************************************************/ | 18 | **************************************************************************/ |
19 | 19 | ||
20 | #ifndef __PWMDOC_H | 20 | #ifndef __PWMDOC_H |
21 | #define __PWMDOC_H | 21 | #define __PWMDOC_H |
22 | 22 | ||
23 | #define PWM_FILE_VER (static_cast<char>(0x05)) | 23 | #define PWM_FILE_VER (static_cast<char>(0x05)) |
24 | 24 | ||
25 | #define PWM_HASH_SHA1 (static_cast<char>(0x01)) | 25 | #define PWM_HASH_SHA1 (static_cast<char>(0x01)) |
26 | #define PWM_HASH_SHA256 (static_cast<char>(0x02)) | 26 | #define PWM_HASH_SHA256 (static_cast<char>(0x02)) |
27 | #define PWM_HASH_SHA384 (static_cast<char>(0x03)) | 27 | #define PWM_HASH_SHA384 (static_cast<char>(0x03)) |
28 | #define PWM_HASH_SHA512 (static_cast<char>(0x04)) | 28 | #define PWM_HASH_SHA512 (static_cast<char>(0x04)) |
29 | #define PWM_HASH_MD5 (static_cast<char>(0x05)) | 29 | #define PWM_HASH_MD5 (static_cast<char>(0x05)) |
30 | #define PWM_HASH_RMD160 (static_cast<char>(0x06)) | 30 | #define PWM_HASH_RMD160 (static_cast<char>(0x06)) |
31 | #define PWM_HASH_TIGER (static_cast<char>(0x07)) | 31 | #define PWM_HASH_TIGER (static_cast<char>(0x07)) |
32 | 32 | ||
33 | #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01)) | 33 | #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01)) |
34 | #define PWM_CRYPT_AES128(static_cast<char>(0x02)) | 34 | #define PWM_CRYPT_AES128(static_cast<char>(0x02)) |
35 | #define PWM_CRYPT_AES192(static_cast<char>(0x03)) | 35 | #define PWM_CRYPT_AES192(static_cast<char>(0x03)) |
36 | #define PWM_CRYPT_AES256(static_cast<char>(0x04)) | 36 | #define PWM_CRYPT_AES256(static_cast<char>(0x04)) |
37 | #define PWM_CRYPT_3DES (static_cast<char>(0x05)) | 37 | #define PWM_CRYPT_3DES (static_cast<char>(0x05)) |
38 | #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06)) | 38 | #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06)) |
39 | #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07)) | 39 | #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07)) |
40 | 40 | ||
41 | #define PWM_COMPRESS_NONE(static_cast<char>(0x00)) | 41 | #define PWM_COMPRESS_NONE(static_cast<char>(0x00)) |
42 | #define PWM_COMPRESS_GZIP(static_cast<char>(0x01)) | 42 | #define PWM_COMPRESS_GZIP(static_cast<char>(0x01)) |
43 | #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02)) | 43 | #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02)) |
44 | 44 | ||
45 | #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0))) | 45 | #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0))) |
46 | #define FILE_ID_HEADER "PWM_PASSWORD_FILE" | 46 | #define FILE_ID_HEADER "PWM_PASSWORD_FILE" |
47 | 47 | ||
48 | 48 | ||
49 | #include "pwmexception.h" | 49 | #include "pwmexception.h" |
50 | #include "pwmdocui.h" | 50 | #include "pwmdocui.h" |
51 | 51 | ||
52 | #include <qobject.h> | 52 | #include <qobject.h> |
53 | #include <qtimer.h> | 53 | #include <qtimer.h> |
54 | #include <qdatetime.h> | 54 | #include <qdatetime.h> |
55 | 55 | ||
56 | #include <kprocess.h> | 56 | #include <kprocess.h> |
57 | 57 | ||
58 | #ifndef PWM_EMBEDDED | 58 | #ifndef PWM_EMBEDDED |
59 | #include "configuration.h" | 59 | #include "configuration.h" |
60 | #else | 60 | #else |
61 | #include <kapplication.h> | 61 | #include <kapplication.h> |
62 | #include <ksyncmanager.h> | 62 | #include <ksyncmanager.h> |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | #include <string> | 65 | #include <string> |
66 | #include <vector> | 66 | #include <vector> |
67 | #include <utility> | 67 | #include <utility> |
68 | 68 | ||
69 | using std::vector; | 69 | using std::vector; |
70 | using std::string; | 70 | using std::string; |
71 | using std::pair; | 71 | using std::pair; |
72 | 72 | ||
73 | /* used in findEntry() function */ | 73 | /* used in findEntry() function */ |
74 | #define SEARCH_IN_DESC (1) | 74 | #define SEARCH_IN_DESC (1) |
75 | #define SEARCH_IN_NAME (1 << 1) | 75 | #define SEARCH_IN_NAME (1 << 1) |
76 | #define SEARCH_IN_PW (1 << 2) | 76 | #define SEARCH_IN_PW (1 << 2) |
77 | #define SEARCH_IN_COMMENT(1 << 3) | 77 | #define SEARCH_IN_COMMENT(1 << 3) |
78 | #define SEARCH_IN_URL (1 << 4) | 78 | #define SEARCH_IN_URL (1 << 4) |
79 | #define SEARCH_IN_LAUNCHER(1 << 5) | 79 | #define SEARCH_IN_LAUNCHER(1 << 5) |
80 | #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \ | 80 | #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \ |
81 | SEARCH_IN_PW | SEARCH_IN_COMMENT| \ | 81 | SEARCH_IN_PW | SEARCH_IN_COMMENT| \ |
82 | SEARCH_IN_URL| SEARCH_IN_LAUNCHER) | 82 | SEARCH_IN_URL| SEARCH_IN_LAUNCHER) |
83 | 83 | ||
84 | /** document deeplocked. Data is out for lunch to disk */ | 84 | /** document deeplocked. Data is out for lunch to disk */ |
85 | #define DOC_STAT_DEEPLOCKED (1) | 85 | #define DOC_STAT_DEEPLOCKED (1) |
86 | /** encrypted document on disk is dirty. data has to go to disk. */ | 86 | /** encrypted document on disk is dirty. data has to go to disk. */ |
87 | #define DOC_STAT_DISK_DIRTY (1 << 1) | 87 | #define DOC_STAT_DISK_DIRTY (1 << 1) |
88 | /** we are using a chipcard to encrypt the data */ | 88 | /** we are using a chipcard to encrypt the data */ |
89 | #define DOC_STAT_USE_CHIPCARD (1 << 2) | 89 | #define DOC_STAT_USE_CHIPCARD (1 << 2) |
90 | /** use "currentPw" to unlock. (This flag is set/unset by a timer) */ | 90 | /** use "currentPw" to unlock. (This flag is set/unset by a timer) */ |
91 | #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3) | 91 | #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3) |
92 | 92 | ||
93 | class PwMDoc; | 93 | class PwMDoc; |
94 | class PwMView; | 94 | class PwMView; |
95 | class QFile; | 95 | class QFile; |
96 | 96 | ||
97 | /* meta data for a PwMDataItem */ | 97 | /* meta data for a PwMDataItem */ |
98 | struct PwMMetaData | 98 | struct PwMMetaData |
99 | { | 99 | { |
100 | PwMMetaData() | 100 | PwMMetaData() |
101 | : updateInt (0) | 101 | : updateInt (0) |
102 | { } | 102 | { } |
103 | /** creation date of the PwMDataItem to which | 103 | /** creation date of the PwMDataItem to which |
104 | * this meta data belongs. | 104 | * this meta data belongs. |
105 | */ | 105 | */ |
106 | QDateTimecreate; | 106 | QDateTimecreate; |
107 | /** becomes valid on this date */ | 107 | /** becomes valid on this date */ |
108 | QDateTimevalid; | 108 | QDateTimevalid; |
109 | /** expire date */ | 109 | /** expire date */ |
110 | QDateTimeexpire; | 110 | QDateTimeexpire; |
111 | /** update date (last updated at this date) */ | 111 | /** update date (last updated at this date) */ |
112 | QDateTimeupdate; | 112 | QDateTimeupdate; |
113 | /** update interval (in minutes). Time since the | 113 | /** update interval (in minutes). Time since the |
114 | * last update to remind the user to update the item. | 114 | * last update to remind the user to update the item. |
115 | * 0 disables. | 115 | * 0 disables. |
116 | */ | 116 | */ |
117 | unsigned long updateInt; | 117 | unsigned long updateInt; |
118 | 118 | ||
119 | //US ENH: enhancements of the filestructure | 119 | //US ENH: enhancements of the filestructure |
120 | /* each entry gets a unique id assigned */ | 120 | /* each entry gets a unique id assigned */ |
121 | string uniqueid; | 121 | string uniqueid; |
122 | 122 | ||
123 | 123 | ||
124 | void clear() | 124 | void clear() |
125 | { | 125 | { |
126 | create = QDateTime(); | 126 | create = QDateTime(); |
127 | expire = QDateTime(); | 127 | expire = QDateTime(); |
128 | update = QDateTime(); | 128 | update = QDateTime(); |
129 | updateInt = 0; | 129 | updateInt = 0; |
130 | uniqueid = KApplication::randomString(8); | 130 | uniqueid = KApplication::randomString(8); |
131 | } | 131 | } |
132 | 132 | ||
133 | inline bool isValid() const | 133 | inline bool isValid() const |
134 | { | 134 | { |
135 | if (valid.isNull()) | 135 | if (valid.isNull()) |
136 | return true; | 136 | return true; |
137 | return (valid < QDateTime::currentDateTime()); | 137 | return (valid < QDateTime::currentDateTime()); |
138 | } | 138 | } |
139 | inline bool isExpired() const | 139 | inline bool isExpired() const |
140 | { | 140 | { |
141 | if (expire.isNull()) | 141 | if (expire.isNull()) |
142 | return false; | 142 | return false; |
143 | return (expire < QDateTime::currentDateTime()); | 143 | return (expire < QDateTime::currentDateTime()); |
144 | } | 144 | } |
145 | inline bool isUpdateIntOver() const | 145 | inline bool isUpdateIntOver() const |
146 | { | 146 | { |
147 | if (updateInt == 0 || | 147 | if (updateInt == 0 || |
148 | update.isNull()) | 148 | update.isNull()) |
149 | return false; | 149 | return false; |
150 | QDateTime d(update); | 150 | QDateTime d(update); |
151 | return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); | 151 | return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); |
152 | } | 152 | } |
153 | }; | 153 | }; |
154 | 154 | ||
155 | struct PwMDataItem | 155 | struct PwMDataItem |
156 | { | 156 | { |
157 | PwMDataItem() | 157 | PwMDataItem() |
158 | : lockStat (true) | 158 | : lockStat (true) |
159 | , listViewPos (-1) | 159 | , listViewPos (-1) |
160 | , binary (false) | 160 | , binary (false) |
161 | , rev (0) | 161 | , rev (0) |
162 | { } | 162 | { } |
163 | 163 | ||
164 | /** password description */ | 164 | /** password description */ |
165 | stringdesc; | 165 | stringdesc; |
166 | /** user-name */ | 166 | /** user-name */ |
167 | stringname; | 167 | stringname; |
168 | /** the password itself */ | 168 | /** the password itself */ |
169 | stringpw; | 169 | stringpw; |
170 | /** some comment */ | 170 | /** some comment */ |
171 | stringcomment; | 171 | stringcomment; |
172 | /** an URL string */ | 172 | /** an URL string */ |
173 | stringurl; | 173 | stringurl; |
174 | /** launcher. Can be executed as a system() command */ | 174 | /** launcher. Can be executed as a system() command */ |
175 | stringlauncher; | 175 | stringlauncher; |
176 | /** locking status. If locked (true), pw is not emitted through getEntry() */ | 176 | /** locking status. If locked (true), pw is not emitted through getEntry() */ |
177 | boollockStat; | 177 | boollockStat; |
178 | /** position of this item in main "list-view" | 178 | /** position of this item in main "list-view" |
179 | * If -1, the position is not yet specified and should be appended to the list | 179 | * If -1, the position is not yet specified and should be appended to the list |
180 | */ | 180 | */ |
181 | intlistViewPos; | 181 | intlistViewPos; |
182 | /** does this entry contain binary data? */ | 182 | /** does this entry contain binary data? */ |
183 | bool binary; | 183 | bool binary; |
184 | /** meta data for this data item. */ | 184 | /** meta data for this data item. */ |
185 | PwMMetaData meta; | 185 | PwMMetaData meta; |
186 | /** data revision counter. This counter can be used | 186 | /** data revision counter. This counter can be used |
187 | * to easily, efficiently determine if this data item | 187 | * to easily, efficiently determine if this data item |
188 | * has changed since some time. | 188 | * has changed since some time. |
189 | * This counter is incremented on every update. | 189 | * This counter is incremented on every update. |
190 | */ | 190 | */ |
191 | unsigned int rev; | 191 | unsigned int rev; |
192 | 192 | ||
193 | void clear(bool clearMeta = true) | 193 | void clear(bool clearMeta = true) |
194 | { | 194 | { |
195 | /* NOTE: Don't use .clear() here to be | 195 | /* NOTE: Don't use .clear() here to be |
196 | * backward compatible with gcc-2 (Debian Woody) | 196 | * backward compatible with gcc-2 (Debian Woody) |
197 | */ | 197 | */ |
198 | desc = ""; | 198 | desc = ""; |
199 | name = ""; | 199 | name = ""; |
200 | pw = ""; | 200 | pw = ""; |
201 | comment = ""; | 201 | comment = ""; |
202 | url = ""; | 202 | url = ""; |
203 | launcher = ""; | 203 | launcher = ""; |
204 | lockStat = true; | 204 | lockStat = true; |
205 | listViewPos = -1; | 205 | listViewPos = -1; |
206 | binary = false; | 206 | binary = false; |
207 | if (clearMeta) | 207 | if (clearMeta) |
208 | meta.clear(); | 208 | meta.clear(); |
209 | } | 209 | } |
210 | //US ENH: we need this operator to compare two items if we have no unique ids | 210 | //US ENH: we need this operator to compare two items if we have no unique ids |
211 | //available. Generaly this happens before the first sync | 211 | //available. Generaly this happens before the first sync |
212 | 212 | ||
213 | bool PwMDataItem::operator==( const PwMDataItem &a ) const | 213 | bool PwMDataItem::operator==( const PwMDataItem &a ) const |
214 | { | 214 | { |
215 | //qDebug("oper==%s", a.desc.c_str()); | 215 | //qDebug("oper==%s", a.desc.c_str()); |
216 | if ( desc != a.desc ) return false; | 216 | if ( desc != a.desc ) return false; |
217 | if ( name != a.name ) return false; | 217 | if ( name != a.name ) return false; |
218 | if ( pw != a.pw ) return false; | 218 | if ( pw != a.pw ) return false; |
219 | if ( comment != a.comment ) return false; | 219 | if ( comment != a.comment ) return false; |
220 | if ( url != a.url ) return false; | 220 | if ( url != a.url ) return false; |
221 | if ( launcher != a.launcher ) return false; | 221 | if ( launcher != a.launcher ) return false; |
222 | //all other field will not be checked. | 222 | //all other field will not be checked. |
223 | return true; | 223 | return true; |
224 | } | 224 | } |
225 | }; | 225 | }; |
226 | 226 | ||
227 | struct PwMCategoryItem | 227 | struct PwMCategoryItem |
228 | { | 228 | { |
229 | /** all PwMDataItems (all passwords) within this category */ | 229 | /** all PwMDataItems (all passwords) within this category */ |
230 | vector<PwMDataItem>d; | 230 | vector<PwMDataItem>d; |
231 | /** category name/description */ | 231 | /** category name/description */ |
232 | string name; | 232 | string name; |
233 | 233 | ||
234 | void clear() | 234 | void clear() |
235 | { | 235 | { |
236 | d.clear(); | 236 | d.clear(); |
237 | name = ""; | 237 | name = ""; |
238 | } | 238 | } |
239 | }; | 239 | }; |
240 | 240 | ||
241 | struct PwMSyncItem | 241 | struct PwMSyncItem |
242 | { | 242 | { |
243 | string syncName; | 243 | string syncName; |
244 | QDateTime lastSyncDate; | 244 | QDateTime lastSyncDate; |
245 | 245 | ||
246 | void clear() | 246 | void clear() |
247 | { | 247 | { |
248 | lastSyncDate = QDateTime(); | 248 | lastSyncDate = QDateTime(); |
249 | syncName = ""; | 249 | syncName = ""; |
250 | } | 250 | } |
251 | }; | 251 | }; |
252 | 252 | ||
253 | struct PwMItem | 253 | struct PwMItem |
254 | { | 254 | { |
255 | vector<PwMCategoryItem> dta; | 255 | vector<PwMCategoryItem> dta; |
256 | vector<PwMSyncItem> syncDta; | 256 | vector<PwMSyncItem> syncDta; |
257 | 257 | ||
258 | void clear() | 258 | void clear() |
259 | { | 259 | { |
260 | dta.clear(); | 260 | dta.clear(); |
261 | syncDta.clear(); | 261 | syncDta.clear(); |
262 | } | 262 | } |
263 | }; | 263 | }; |
264 | 264 | ||
265 | 265 | ||
266 | /** "Function Object" for sort()ing PwMDataItem::listViewPos */ | 266 | /** "Function Object" for sort()ing PwMDataItem::listViewPos */ |
267 | class dta_lvp_greater | 267 | class dta_lvp_greater |
268 | { | 268 | { |
269 | public: | 269 | public: |
270 | bool operator() (const pair<unsigned int, unsigned int> &d1, | 270 | bool operator() (const pair<unsigned int, unsigned int> &d1, |
271 | const pair<unsigned int, unsigned int> &d2) | 271 | const pair<unsigned int, unsigned int> &d2) |
272 | { | 272 | { |
273 | return d1.second > d2.second; | 273 | return d1.second > d2.second; |
274 | } | 274 | } |
275 | }; | 275 | }; |
276 | 276 | ||
277 | /** list of PwMDoc documents and it's IDs */ | 277 | /** list of PwMDoc documents and it's IDs */ |
278 | class PwMDocList | 278 | class PwMDocList |
279 | { | 279 | { |
280 | public: | 280 | public: |
281 | struct listItem | 281 | struct listItem |
282 | { | 282 | { |
283 | /** document filename (known as ID, here) */ | 283 | /** document filename (known as ID, here) */ |
284 | string docId; | 284 | string docId; |
285 | /** pointer to the document class */ | 285 | /** pointer to the document class */ |
286 | PwMDoc *doc; | 286 | PwMDoc *doc; |
287 | }; | 287 | }; |
288 | 288 | ||
289 | PwMDocList() {} | 289 | PwMDocList() {} |
290 | 290 | ||
291 | /** add a new item to the list */ | 291 | /** add a new item to the list */ |
292 | void add(PwMDoc *doc, const string &id); | 292 | void add(PwMDoc *doc, const string &id); |
293 | /** changes the contents of an existing item */ | 293 | /** changes the contents of an existing item */ |
294 | void edit(PwMDoc *doc, const string &newId); | 294 | void edit(PwMDoc *doc, const string &newId); |
295 | /** remove the given item */ | 295 | /** remove the given item */ |
296 | void del(PwMDoc *doc); | 296 | void del(PwMDoc *doc); |
297 | /** get the item at index */ | 297 | /** get the item at index */ |
298 | listItem getAt(int index) | 298 | listItem getAt(int index) |
299 | { return docList[index]; } | 299 | { return docList[index]; } |
300 | /** find an entry with this id */ | 300 | /** find an entry with this id */ |
301 | bool find(const string &id, listItem *ret = 0); | 301 | bool find(const string &id, listItem *ret = 0); |
302 | /** returns a copy of the list */ | 302 | /** returns a copy of the list */ |
303 | const vector<listItem>* getList() const | 303 | const vector<listItem>* getList() const |
304 | { return &docList; } | 304 | { return &docList; } |
305 | 305 | ||
306 | 306 | ||
307 | /** returns a new unique number to extend the name of | 307 | /** returns a new unique number to extend the name of |
308 | * an unnamed document. | 308 | * an unnamed document. |
309 | */ | 309 | */ |
310 | static unsigned int getNewUnnamedNumber() | 310 | static unsigned int getNewUnnamedNumber() |
311 | { return unnamedDocCnt++; } | 311 | { return unnamedDocCnt++; } |
312 | 312 | ||
313 | protected: | 313 | protected: |
314 | /* Hm, I think we shouldn't really use a "list" here, should we? | 314 | /* Hm, I think we shouldn't really use a "list" here, should we? |
315 | * So I decided to actually use a vector. | 315 | * So I decided to actually use a vector. |
316 | */ | 316 | */ |
317 | vector<listItem> docList; | 317 | vector<listItem> docList; |
318 | /** This value is used to get a new number for yet unnamed | 318 | /** This value is used to get a new number for yet unnamed |
319 | * documents. It is incremented on every request. So it's | 319 | * documents. It is incremented on every request. So it's |
320 | * theoretically possible to overflow it, but... :) | 320 | * theoretically possible to overflow it, but... :) |
321 | */ | 321 | */ |
322 | static unsigned int unnamedDocCnt; | 322 | static unsigned int unnamedDocCnt; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | /** implements timers for the document */ | 325 | /** implements timers for the document */ |
326 | class DocTimer : public QObject | 326 | class DocTimer : public QObject |
327 | { | 327 | { |
328 | Q_OBJECT | 328 | Q_OBJECT |
329 | public: | 329 | public: |
330 | enum TimerIDs | 330 | enum TimerIDs |
331 | { | 331 | { |
332 | id_mpwTimer, | 332 | id_mpwTimer, |
333 | id_autoLockTimer, | 333 | id_autoLockTimer, |
334 | id_metaCheckTimer | 334 | id_metaCheckTimer |
335 | }; | 335 | }; |
336 | 336 | ||
337 | public: | 337 | public: |
338 | DocTimer(PwMDoc *_doc); | 338 | DocTimer(PwMDoc *_doc); |
339 | ~DocTimer(); | 339 | ~DocTimer(); |
340 | 340 | ||
341 | /** start the timer */ | 341 | /** start the timer */ |
342 | void start(TimerIDs timer); | 342 | void start(TimerIDs timer); |
343 | /** stop the timer */ | 343 | /** stop the timer */ |
344 | void stop(TimerIDs timer); | 344 | void stop(TimerIDs timer); |
345 | /** get the lock for a timer. | 345 | /** get the lock for a timer. |
346 | * This lock is a recursive lock. When a lock is | 346 | * This lock is a recursive lock. When a lock is |
347 | * held, the timer will be stopped and timeout is | 347 | * held, the timer will be stopped and timeout is |
348 | * guaranteed to not happen | 348 | * guaranteed to not happen |
349 | */ | 349 | */ |
350 | void getLock(TimerIDs timer); | 350 | void getLock(TimerIDs timer); |
351 | /** put a recursive timer lock */ | 351 | /** put a recursive timer lock */ |
352 | void putLock(TimerIDs timer); | 352 | void putLock(TimerIDs timer); |
353 | 353 | ||
354 | protected slots: | 354 | protected slots: |
355 | /** timeout slot for the mpw timer */ | 355 | /** timeout slot for the mpw timer */ |
356 | void mpwTimeout(); | 356 | void mpwTimeout(); |
357 | /** timeout slot for the autoLock timer */ | 357 | /** timeout slot for the autoLock timer */ |
358 | void autoLockTimeout(); | 358 | void autoLockTimeout(); |
359 | /** timeout slot for the metaCheck timer */ | 359 | /** timeout slot for the metaCheck timer */ |
360 | void metaCheckTimeout(); | 360 | void metaCheckTimeout(); |
361 | 361 | ||
362 | protected: | 362 | protected: |
363 | /** pointer to the document associated with this timer. */ | 363 | /** pointer to the document associated with this timer. */ |
364 | PwMDoc *doc; | 364 | PwMDoc *doc; |
365 | /** timer object for mpw timer */ | 365 | /** timer object for mpw timer */ |
366 | QTimer *mpwTimer; | 366 | QTimer *mpwTimer; |
367 | /** timer object for the autoLock timer */ | 367 | /** timer object for the autoLock timer */ |
368 | QTimer *autoLockTimer; | 368 | QTimer *autoLockTimer; |
369 | /** timer object for the metaCheck timer */ | 369 | /** timer object for the metaCheck timer */ |
370 | QTimer *metaCheckTimer; | 370 | QTimer *metaCheckTimer; |
371 | /** lock counter for the mpw timer */ | 371 | /** lock counter for the mpw timer */ |
372 | unsigned int mpwLock; | 372 | unsigned int mpwLock; |
373 | /** lock counter for the autoLock timer */ | 373 | /** lock counter for the autoLock timer */ |
374 | unsigned int autoLockLock; | 374 | unsigned int autoLockLock; |
375 | /** lock counter for the metaCheck timer */ | 375 | /** lock counter for the metaCheck timer */ |
376 | unsigned int metaCheckLock; | 376 | unsigned int metaCheckLock; |
377 | }; | 377 | }; |
378 | 378 | ||
379 | /** Document class for PwM */ | 379 | /** Document class for PwM */ |
380 | //US ENH: derived from KSyncInterfaces, to get called by PwM when a sync is required. | 380 | //US ENH: derived from KSyncInterfaces, to get called by PwM when a sync is required. |
381 | // But PwMDoc is handling the sync by itself. | 381 | // But PwMDoc is handling the sync by itself. |
382 | class PwMDoc : public PwMDocUi, public KSyncInterface | 382 | class PwMDoc : public PwMDocUi, public KSyncInterface |
383 | 383 | ||
384 | { | 384 | { |
385 | Q_OBJECT | 385 | Q_OBJECT |
386 | friend class DocTimer; | 386 | friend class DocTimer; |
387 | 387 | ||
388 | public: | 388 | public: |
389 | /** construtor */ | 389 | /** construtor */ |
390 | PwMDoc(QObject* parent = 0, const char *name = 0); | 390 | PwMDoc(QObject* parent = 0, const char *name = 0); |
391 | /** destructor */ | 391 | /** destructor */ |
392 | ~PwMDoc(); | 392 | ~PwMDoc(); |
393 | 393 | ||
394 | /** returns a pointer to a list of all open documents */ | 394 | /** returns a pointer to a list of all open documents */ |
395 | static PwMDocList* getOpenDocList() | 395 | static PwMDocList* getOpenDocList() |
396 | { return &openDocList; } | 396 | { return &openDocList; } |
397 | 397 | ||
398 | /** flag document dirty. dta changed */ | 398 | /** flag document dirty. dta changed */ |
399 | void flagDirty() | 399 | void flagDirty() |
400 | { | 400 | { |
401 | setDocStatFlag(DOC_STAT_DISK_DIRTY); | 401 | setDocStatFlag(DOC_STAT_DISK_DIRTY); |
402 | emitDataChanged(this); | 402 | emitDataChanged(this); |
403 | } | 403 | } |
404 | /** modified? */ | 404 | /** modified? */ |
405 | bool isDirty() | 405 | bool isDirty() |
406 | { return getDocStatFlag(DOC_STAT_DISK_DIRTY); } | 406 | { return getDocStatFlag(DOC_STAT_DISK_DIRTY); } |
407 | /** save document to disk */ | 407 | /** save document to disk */ |
408 | PwMerror saveDoc(char compress, const QString *file = 0); | 408 | PwMerror saveDoc(char compress, const QString *file = 0); |
409 | /** read document from file. | 409 | /** read document from file. |
410 | * "openLocked is must be set to either of these values: | 410 | * "openLocked is must be set to either of these values: |
411 | * 0 == open with all entries unlocked | 411 | * 0 == open with all entries unlocked |
412 | * 1 == open with all entries locked | 412 | * 1 == open with all entries locked |
413 | * 2 == open deep-locked | 413 | * 2 == open deep-locked |
414 | */ | 414 | */ |
415 | PwMerror openDoc(const QString *file, int openLocked); | 415 | PwMerror openDoc(const QString *file, int openLocked); |
416 | /** export document to ascii-textfile */ | 416 | /** export document to ascii-textfile */ |
417 | PwMerror exportToText(const QString *file); | 417 | PwMerror exportToText(const QString *file); |
418 | /** export document to gpasman / kpasman file */ | 418 | /** export document to gpasman / kpasman file */ |
419 | PwMerror exportToGpasman(const QString *file); | 419 | PwMerror exportToGpasman(const QString *file); |
420 | /** import document from ascii-textfile */ | 420 | /** import document from ascii-textfile */ |
421 | PwMerror importFromText(const QString *file, int format = -1); | 421 | PwMerror importFromText(const QString *file, int format = -1); |
422 | /** import document from gpasman / kpasman file */ | 422 | /** import document from gpasman / kpasman file */ |
423 | PwMerror importFromGpasman(const QString *file); | 423 | PwMerror importFromGpasman(const QString *file); |
424 | /** add new entry */ | 424 | /** add new entry */ |
425 | PwMerror addEntry(const QString &category, PwMDataItem *d, | 425 | PwMerror addEntry(const QString &category, PwMDataItem *d, |
426 | bool dontFlagDirty = false, bool updateMeta = true); | 426 | bool dontFlagDirty = false, bool updateMeta = true); |
427 | /** add new category. This function doesn't flag the document dirty! */ | 427 | /** add new category. This function doesn't flag the document dirty! */ |
428 | PwMerror addCategory(const QString &category, unsigned int *categoryIndex, | 428 | PwMerror addCategory(const QString &category, unsigned int *categoryIndex, |
429 | bool checkIfExist = true); | 429 | bool checkIfExist = true); |
430 | /** rename an existing category */ | 430 | /** rename an existing category */ |
431 | bool renameCategory(const QString &category, const QString &newName); | 431 | bool renameCategory(const QString &category, const QString &newName); |
432 | /** rename an existing category */ | 432 | /** rename an existing category */ |
433 | bool renameCategory(unsigned int category, const QString &newName, | 433 | bool renameCategory(unsigned int category, const QString &newName, |
434 | bool dontFlagDirty = false); | 434 | bool dontFlagDirty = false); |
435 | /** delete an existing category */ | 435 | /** delete an existing category */ |
436 | bool delCategory(const QString &category); | 436 | bool delCategory(const QString &category); |
437 | /** delete an existing category */ | 437 | /** delete an existing category */ |
438 | bool delCategory(unsigned int category, bool dontFlagDirty = false); | 438 | bool delCategory(unsigned int category, bool dontFlagDirty = false); |
439 | /** returns a list of all category-names */ | 439 | /** returns a list of all category-names */ |
440 | void getCategoryList(vector<string> *list); | 440 | void getCategoryList(vector<string> *list); |
441 | /** returns a list of all category-names */ | 441 | /** returns a list of all category-names */ |
442 | void getCategoryList(QStringList *list); | 442 | void getCategoryList(QStringList *list); |
443 | /** returns a list of all entry-descs in the given category */ | 443 | /** returns a list of all entry-descs in the given category */ |
444 | void getEntryList(const QString &category, QStringList *list); | 444 | void getEntryList(const QString &category, QStringList *list); |
445 | /** returns a list of all entry-descs in the given category */ | 445 | /** returns a list of all entry-descs in the given category */ |
446 | void getEntryList(const QString &category, vector<string> *list); | 446 | void getEntryList(const QString &category, vector<string> *list); |
447 | /** returns a list of all entry-descs in the given category */ | 447 | /** returns a list of all entry-descs in the given category */ |
448 | void getEntryList(unsigned int category, vector<string> *list); | 448 | void getEntryList(unsigned int category, vector<string> *list); |
449 | /** returns a list of all entry-descs in the given category */ | 449 | /** returns a list of all entry-descs in the given category */ |
450 | void getEntryList(unsigned int category, QStringList *list); | 450 | void getEntryList(unsigned int category, QStringList *list); |
451 | /** delete entry */ | 451 | /** delete entry */ |
452 | bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false); | 452 | bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false); |
453 | /** delete entry */ | 453 | /** delete entry */ |
454 | bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false); | 454 | bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false); |
455 | /** edit entry */ | 455 | /** edit entry */ |
456 | bool editEntry(const QString &oldCategory, const QString &newCategory, | 456 | bool editEntry(const QString &oldCategory, const QString &newCategory, |
457 | unsigned int index, PwMDataItem *d, bool updateMeta = true); | 457 | unsigned int index, PwMDataItem *d, bool updateMeta = true); |
458 | /** edit entry */ | 458 | /** edit entry */ |
459 | bool editEntry(unsigned int oldCategory, const QString &newCategory, | 459 | bool editEntry(unsigned int oldCategory, const QString &newCategory, |
460 | unsigned int index, PwMDataItem *d, bool updateMeta = true); | 460 | unsigned int index, PwMDataItem *d, bool updateMeta = true); |
461 | /** finds the category with the "name" and return it's index */ | 461 | /** finds the category with the "name" and return it's index */ |
462 | bool findCategory(const QString &name, unsigned int *index); | 462 | bool findCategory(const QString &name, unsigned int *index); |
463 | /** search for an entry "find" and check while searching only for | 463 | /** search for an entry "find" and check while searching only for |
464 | * the data-fields specified by "searchIn". To set the "searchIn" | 464 | * the data-fields specified by "searchIn". To set the "searchIn" |
465 | * value, we may use one or more of the SEARCH_IN_* defines at | 465 | * value, we may use one or more of the SEARCH_IN_* defines at |
466 | * the top of this header-file. It returns the positions of all | 466 | * the top of this header-file. It returns the positions of all |
467 | * matched entries in "foundPositions". If "breakAfterFound" is true, | 467 | * matched entries in "foundPositions". If "breakAfterFound" is true, |
468 | * the function terminates after the first occurence of the entry | 468 | * the function terminates after the first occurence of the entry |
469 | * and doesn't go on searching. So foundPositions->size() is never | 469 | * and doesn't go on searching. So foundPositions->size() is never |
470 | * > 1 if breakAfterFound is true. | 470 | * > 1 if breakAfterFound is true. |
471 | */ | 471 | */ |
472 | void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, | 472 | void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, |
473 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, | 473 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, |
474 | bool caseSensitive = true, bool exactWordMatch = true, | 474 | bool caseSensitive = true, bool exactWordMatch = true, |
475 | bool sortByLvp = false); | 475 | bool sortByLvp = false); |
476 | /** see the above funtion. This function allows to set the category by name. */ | 476 | /** see the above funtion. This function allows to set the category by name. */ |
477 | void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, | 477 | void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, |
478 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, | 478 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, |
479 | bool caseSensitive = true, bool exactWordMatch = true, | 479 | bool caseSensitive = true, bool exactWordMatch = true, |
480 | bool sortByLvp = false); | 480 | bool sortByLvp = false); |
481 | /** returns number of entries */ | 481 | /** returns number of entries */ |
482 | unsigned int numEntries(const QString &category); | 482 | unsigned int numEntries(const QString &category); |
483 | unsigned int numEntries(unsigned int category) | 483 | unsigned int numEntries(unsigned int category) |
484 | { return dti.dta[category].d.size(); } | 484 | { return dti.dta[category].d.size(); } |
485 | /** returns number of categories */ | 485 | /** returns number of categories */ |
486 | unsigned int numCategories() | 486 | unsigned int numCategories() |
487 | { return dti.dta.size(); } | 487 | { return dti.dta.size(); } |
488 | /** returns the name of the category at "index" */ | 488 | /** returns the name of the category at "index" */ |
489 | const string* getCategory(unsigned int index) | 489 | const string* getCategory(unsigned int index) |
490 | { return (&(dti.dta[index].name)); } | 490 | { return (&(dti.dta[index].name)); } |
491 | 491 | ||
492 | /** returns the data of item at "index". | 492 | /** returns the data of item at "index". |
493 | * It unlocks the entry if it's locked and unlockIfLocked is true. | 493 | * It unlocks the entry if it's locked and unlockIfLocked is true. |
494 | * If the entry is locked, but unlockIfLocked is false, it'll not return | 494 | * If the entry is locked, but unlockIfLocked is false, it'll not return |
495 | * the pw. | 495 | * the pw. |
496 | */ | 496 | */ |
497 | bool getEntry(const QString &category, unsigned int index, | 497 | bool getEntry(const QString &category, unsigned int index, |
498 | PwMDataItem *d, bool unlockIfLocked = false); | 498 | PwMDataItem *d, bool unlockIfLocked = false); |
499 | bool getEntry(unsigned int category, unsigned int index, | 499 | bool getEntry(unsigned int category, unsigned int index, |
500 | PwMDataItem *d, bool unlockIfLocked = false); | 500 | PwMDataItem *d, bool unlockIfLocked = false); |
501 | /** returns the comment-string by looking at the category | 501 | /** returns the comment-string by looking at the category |
502 | * and the listViewPos | 502 | * and the listViewPos |
503 | */ | 503 | */ |
504 | PwMerror getCommentByLvp(const QString &category, int listViewPos, | 504 | PwMerror getCommentByLvp(const QString &category, int listViewPos, |
505 | string *foundComment); | 505 | string *foundComment); |
506 | /** checks if a password is already available. (currentPw) */ | 506 | /** checks if a password is already available. (currentPw) */ |
507 | bool isPwAvailable() | 507 | bool isPwAvailable() |
508 | { return (currentPw != ""); } | 508 | { return (currentPw != ""); } |
509 | /** un/lock entry at "index". If needed, ask for password. */ | 509 | /** un/lock entry at "index". If needed, ask for password. */ |
510 | bool lockAt(const QString &category, unsigned int index, | 510 | bool lockAt(const QString &category, unsigned int index, |
511 | bool lock = true); | 511 | bool lock = true); |
512 | bool lockAt(unsigned int category, unsigned int index, | 512 | bool lockAt(unsigned int category, unsigned int index, |
513 | bool lock = true); | 513 | bool lock = true); |
514 | /** returns the lock-status at "index" */ | 514 | /** returns the lock-status at "index" */ |
515 | bool isLocked(const QString &category, unsigned int index); | 515 | bool isLocked(const QString &category, unsigned int index); |
516 | bool isLocked(unsigned int category, unsigned int index) | 516 | bool isLocked(unsigned int category, unsigned int index) |
517 | { return dti.dta[category].d[index].lockStat; } | 517 | { return dti.dta[category].d[index].lockStat; } |
518 | /** returns the deeplock status */ | 518 | /** returns the deeplock status */ |
519 | bool isDeepLocked() | 519 | bool isDeepLocked() |
520 | { return getDocStatFlag(DOC_STAT_DEEPLOCKED); } | 520 | { return getDocStatFlag(DOC_STAT_DEEPLOCKED); } |
521 | /** (un)lock all entries */ | 521 | /** (un)lock all entries */ |
522 | bool lockAll(bool lock); | 522 | bool lockAll(bool lock); |
523 | /** unlocks all entries tempoarly. | 523 | /** unlocks all entries tempoarly. |
524 | * 1st NOTE: Be very careful with this function! :) | 524 | * 1st NOTE: Be very careful with this function! :) |
525 | * 2nd NOTE: After you have called unlockAll_Tempoary(); , | 525 | * 2nd NOTE: After you have called unlockAll_Tempoary(); , |
526 | * please DON'T forget to call unlockAll_Tempoary(true); | 526 | * please DON'T forget to call unlockAll_Tempoary(true); |
diff --git a/pwmanager/pwmanager/pwmdocui.cpp b/pwmanager/pwmanager/pwmdocui.cpp index 7b8e0ee..6ddb6f5 100644 --- a/pwmanager/pwmanager/pwmdocui.cpp +++ b/pwmanager/pwmanager/pwmdocui.cpp | |||
@@ -1,457 +1,467 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * * | 2 | * * |
3 | * copyright (C) 2003, 2004 by Michael Buesch * | 3 | * copyright (C) 2003, 2004 by Michael Buesch * |
4 | * email: mbuesch@freenet.de * | 4 | * email: mbuesch@freenet.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License version 2 * | 7 | * it under the terms of the GNU General Public License version 2 * |
8 | * as published by the Free Software Foundation. * | 8 | * as published by the Free Software Foundation. * |
9 | * * | 9 | * * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | /*************************************************************************** | 12 | /*************************************************************************** |
13 | * copyright (C) 2004 by Ulf Schenk | 13 | * copyright (C) 2004 by Ulf Schenk |
14 | * This file is originaly based on version 1.0.1 of pwmanager | 14 | * This file is originaly based on version 1.0.1 of pwmanager |
15 | * and was modified to run on embedded devices that run microkde | 15 | * and was modified to run on embedded devices that run microkde |
16 | * | 16 | * |
17 | * $Id$ | 17 | * $Id$ |
18 | **************************************************************************/ | 18 | **************************************************************************/ |
19 | 19 | ||
20 | #include "pwmdocui.h" | 20 | #include "pwmdocui.h" |
21 | #include "setmasterpwwndimpl.h" | 21 | #include "setmasterpwwndimpl.h" |
22 | #include "getmasterpwwndimpl.h" | 22 | #include "getmasterpwwndimpl.h" |
23 | #include "pwmexception.h" | 23 | #include "pwmexception.h" |
24 | #include "getkeycardwnd.h" | 24 | #include "getkeycardwnd.h" |
25 | #include "pwm.h" | 25 | #include "pwm.h" |
26 | #include "globalstuff.h" | 26 | #include "globalstuff.h" |
27 | #include "spinforsignal.h" | 27 | #include "spinforsignal.h" |
28 | 28 | ||
29 | #include <qlineedit.h> | 29 | #include <qlineedit.h> |
30 | #include <qtabwidget.h> | 30 | #include <qtabwidget.h> |
31 | 31 | ||
32 | #include <kmessagebox.h> | 32 | #include <kmessagebox.h> |
33 | #include <kfiledialog.h> | 33 | #include <kfiledialog.h> |
34 | 34 | ||
35 | #ifndef PWM_EMBEDDED | 35 | #ifndef PWM_EMBEDDED |
36 | #include <kwin.h> | 36 | #include <kwin.h> |
37 | #else | 37 | #else |
38 | #include <qdir.h> | 38 | #include <qdir.h> |
39 | #include "pwmprefs.h" | 39 | #include "pwmprefs.h" |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | 42 | ||
43 | #ifdef CONFIG_KEYCARD | 43 | #ifdef CONFIG_KEYCARD |
44 | # include "pwmkeycard.h" | 44 | # include "pwmkeycard.h" |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | 47 | ||
48 | PwMDocUi::PwMDocUi(QObject *parent, const char *name) | 48 | PwMDocUi::PwMDocUi(QObject *parent, const char *name) |
49 | : QObject(parent, name) | 49 | : QObject(parent, name) |
50 | { | 50 | { |
51 | currentView = 0; | 51 | currentView = 0; |
52 | keyCard = 0; | 52 | keyCard = 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | PwMDocUi::~PwMDocUi() | 55 | PwMDocUi::~PwMDocUi() |
56 | { | 56 | { |
57 | } | 57 | } |
58 | 58 | ||
59 | QString PwMDocUi::requestMpw(bool chipcard) | 59 | QString PwMDocUi::requestMpw(bool chipcard) |
60 | { | 60 | { |
61 | QString pw; | 61 | QString pw; |
62 | 62 | ||
63 | if (chipcard) { | 63 | if (chipcard) { |
64 | #ifdef CONFIG_KEYCARD | 64 | #ifdef CONFIG_KEYCARD |
65 | PWM_ASSERT(keyCard); | 65 | PWM_ASSERT(keyCard); |
66 | uint32_t id; | 66 | uint32_t id; |
67 | string ret; | 67 | string ret; |
68 | SpinForSignal *spinner = keyCard->getSpinner(); | 68 | SpinForSignal *spinner = keyCard->getSpinner(); |
69 | connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), | 69 | connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), |
70 | spinner, SLOT(u32_str_slot(uint32_t, const string &))); | 70 | spinner, SLOT(u32_str_slot(uint32_t, const string &))); |
71 | keyCard->getKey(); | 71 | keyCard->getKey(); |
72 | spinner->spin(&id, &ret); | 72 | spinner->spin(&id, &ret); |
73 | disconnect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), | 73 | disconnect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), |
74 | spinner, SLOT(u32_str_slot(uint32_t, const string &))); | 74 | spinner, SLOT(u32_str_slot(uint32_t, const string &))); |
75 | if (ret == "") | 75 | if (ret == "") |
76 | return ""; | 76 | return ""; |
77 | pw = ret.c_str(); | 77 | pw = ret.c_str(); |
78 | #else // CONFIG_KEYCARD | 78 | #else // CONFIG_KEYCARD |
79 | no_keycard_support_msg_box(currentView); | 79 | no_keycard_support_msg_box(currentView); |
80 | #endif // CONFIG_KEYCARD | 80 | #endif // CONFIG_KEYCARD |
81 | } else { | 81 | } else { |
82 | #ifndef PWM_EMBEDDED | 82 | #ifndef PWM_EMBEDDED |
83 | GetMasterPwWndImpl pwWnd; | 83 | GetMasterPwWndImpl pwWnd; |
84 | KWin::setState(pwWnd.winId(), NET::StaysOnTop); | 84 | KWin::setState(pwWnd.winId(), NET::StaysOnTop); |
85 | #else | 85 | #else |
86 | GetMasterPwWndImpl pwWnd; | 86 | GetMasterPwWndImpl pwWnd; |
87 | #endif | 87 | #endif |
88 | if (pwWnd.exec() != 1) | 88 | if (pwWnd.exec() != 1) |
89 | return ""; | 89 | return ""; |
90 | pw = pwWnd.pwLineEdit->text(); | 90 | pw = pwWnd.pwLineEdit->text(); |
91 | } | 91 | } |
92 | 92 | ||
93 | return pw; | 93 | return pw; |
94 | } | 94 | } |
95 | 95 | ||
96 | QString PwMDocUi::requestNewMpw(bool *chipcard) | 96 | QString PwMDocUi::requestNewMpw(bool *chipcard) |
97 | { | 97 | { |
98 | QString pw; | 98 | QString pw; |
99 | SetMasterPwWndImpl pwWnd(currentView); | 99 | SetMasterPwWndImpl pwWnd(currentView); |
100 | pwWnd.setPwMKeyCard(keyCard); | 100 | pwWnd.setPwMKeyCard(keyCard); |
101 | if (!chipcard) { | 101 | if (!chipcard) { |
102 | #ifndef PWM_EMBEDDED | 102 | #ifndef PWM_EMBEDDED |
103 | pwWnd.mainTab->removePage(pwWnd.mainTab->page(1)); | 103 | pwWnd.mainTab->removePage(pwWnd.mainTab->page(1)); |
104 | #else | 104 | #else |
105 | pwWnd.mainTab->removePage(pwWnd.tab_2); | 105 | pwWnd.mainTab->removePage(pwWnd.tab_2); |
106 | #endif | 106 | #endif |
107 | } | 107 | } |
108 | 108 | ||
109 | if (pwWnd.exec() != 1) | 109 | if (pwWnd.exec() != 1) |
110 | return ""; | 110 | return ""; |
111 | pw = pwWnd.getPw(chipcard).c_str(); | 111 | pw = pwWnd.getPw(chipcard).c_str(); |
112 | 112 | ||
113 | return pw; | 113 | return pw; |
114 | } | 114 | } |
115 | 115 | ||
116 | QString PwMDocUi::requestMpwChange(const QString *currentPw, bool *chipcard) | 116 | QString PwMDocUi::requestMpwChange(const QString *currentPw, bool *chipcard) |
117 | { | 117 | { |
118 | QString pw(requestMpw(*chipcard)); | 118 | QString pw(requestMpw(*chipcard)); |
119 | if (pw == "") | 119 | if (pw == "") |
120 | return ""; | 120 | return ""; |
121 | if (pw != *currentPw) { | 121 | if (pw != *currentPw) { |
122 | wrongMpwMsgBox(*chipcard); | 122 | wrongMpwMsgBox(*chipcard); |
123 | return ""; | 123 | return ""; |
124 | } | 124 | } |
125 | 125 | ||
126 | pw = requestNewMpw(chipcard); | 126 | pw = requestNewMpw(chipcard); |
127 | if (pw == "") | 127 | if (pw == "") |
128 | return ""; | 128 | return ""; |
129 | return pw; | 129 | return pw; |
130 | } | 130 | } |
131 | 131 | ||
132 | void PwMDocUi::wrongMpwMsgBox(bool chipcard, QString prefix, QString postfix) | 132 | void PwMDocUi::wrongMpwMsgBox(bool chipcard, QString prefix, QString postfix) |
133 | { | 133 | { |
134 | QString msg; | 134 | QString msg; |
135 | if (prefix != "") { | 135 | if (prefix != "") { |
136 | msg += prefix; | 136 | msg += prefix; |
137 | msg += "\n"; | 137 | msg += "\n"; |
138 | } | 138 | } |
139 | 139 | ||
140 | if (chipcard) { | 140 | if (chipcard) { |
141 | msg += i18n("Wrong key-card!\n" | 141 | msg += i18n("Wrong key-card!\n" |
142 | "Please try again with the\n" | 142 | "Please try again with the\n" |
143 | "correct key-card."); | 143 | "correct key-card."); |
144 | } else { | 144 | } else { |
145 | msg += i18n("Wrong master-password!\n" | 145 | msg += i18n("Wrong master-password!\n" |
146 | "Please try again."); | 146 | "Please try again."); |
147 | } | 147 | } |
148 | 148 | ||
149 | if (postfix != "") { | 149 | if (postfix != "") { |
150 | msg += "\n"; | 150 | msg += "\n"; |
151 | msg += postfix; | 151 | msg += postfix; |
152 | } | 152 | } |
153 | KMessageBox::error(currentView, msg, | 153 | KMessageBox::error(currentView, msg, |
154 | (chipcard) ? (i18n("wrong chipcard")) | 154 | (chipcard) ? (i18n("wrong chipcard")) |
155 | : (i18n("password error"))); | 155 | : (i18n("password error"))); |
156 | } | 156 | } |
157 | 157 | ||
158 | void PwMDocUi::noMpwMsgBox(bool chipcard, QString prefix, QString postfix) | 158 | void PwMDocUi::noMpwMsgBox(bool chipcard, QString prefix, QString postfix) |
159 | { | 159 | { |
160 | QString msg; | 160 | QString msg; |
161 | if (prefix != "") { | 161 | if (prefix != "") { |
162 | msg += prefix; | 162 | msg += prefix; |
163 | msg += "\n"; | 163 | msg += "\n"; |
164 | } | 164 | } |
165 | 165 | ||
166 | if (chipcard) { | 166 | if (chipcard) { |
167 | msg += i18n("No key-card found!\n" | 167 | msg += i18n("No key-card found!\n" |
168 | "Please insert the\n" | 168 | "Please insert the\n" |
169 | "correct key-card."); | 169 | "correct key-card."); |
170 | } else { | 170 | } else { |
171 | msg += i18n("No master-password given!"); | 171 | msg += i18n("No master-password given!"); |
172 | } | 172 | } |
173 | 173 | ||
174 | if (postfix != "") { | 174 | if (postfix != "") { |
175 | msg += "\n"; | 175 | msg += "\n"; |
176 | msg += postfix; | 176 | msg += postfix; |
177 | } | 177 | } |
178 | KMessageBox::error(currentView, msg, | 178 | KMessageBox::error(currentView, msg, |
179 | (chipcard) ? (i18n("no chipcard")) | 179 | (chipcard) ? (i18n("no chipcard")) |
180 | : (i18n("password error"))); | 180 | : (i18n("password error"))); |
181 | } | 181 | } |
182 | 182 | ||
183 | void PwMDocUi::rootAlertMsgBox() | 183 | void PwMDocUi::rootAlertMsgBox() |
184 | { | 184 | { |
185 | KMessageBox::error(currentView, | 185 | KMessageBox::error(currentView, |
186 | i18n("This feature is not available,n" | 186 | i18n("This feature is not available,n" |
187 | "if you execute PwM with \"root\" \n" | 187 | "if you execute PwM with \"root\" \n" |
188 | "UID 0 privileges, for security reasons!"), | 188 | "UID 0 privileges, for security reasons!"), |
189 | i18n("not allowed as root!")); | 189 | i18n("not allowed as root!")); |
190 | } | 190 | } |
191 | 191 | ||
192 | void PwMDocUi::cantDeeplock_notSavedMsgBox() | 192 | void PwMDocUi::cantDeeplock_notSavedMsgBox() |
193 | { | 193 | { |
194 | KMessageBox::error(currentView, | 194 | KMessageBox::error(currentView, |
195 | i18n("Can't deep-lock, because the document\n" | 195 | i18n("Can't deep-lock, because the document\n" |
196 | "hasn't been saved, yet. Please save\n" | 196 | "hasn't been saved, yet. Please save\n" |
197 | "to a file and try again."), | 197 | "to a file and try again."), |
198 | i18n("not saved, yet")); | 198 | i18n("not saved, yet")); |
199 | } | 199 | } |
200 | 200 | ||
201 | void PwMDocUi::gpmPwLenErrMsgBox() | 201 | void PwMDocUi::gpmPwLenErrMsgBox() |
202 | { | 202 | { |
203 | KMessageBox::error(currentView, | 203 | KMessageBox::error(currentView, |
204 | i18n("GPasman does not support passwords\n" | 204 | i18n("GPasman does not support passwords\n" |
205 | "shorter than 4 characters! Please try\n" | 205 | "shorter than 4 characters! Please try\n" |
206 | "again with a longer password."), | 206 | "again with a longer password."), |
207 | i18n("password too short")); | 207 | i18n("password too short")); |
208 | } | 208 | } |
209 | 209 | ||
210 | int PwMDocUi::dirtyAskSave(const QString &docTitle) | 210 | int PwMDocUi::dirtyAskSave(const QString &docTitle) |
211 | { | 211 | { |
212 | int ret; | 212 | int ret; |
213 | #ifndef PWM_EMBEDDED | 213 | #ifndef PWM_EMBEDDED |
214 | ret = KMessageBox::questionYesNoCancel(currentView, | 214 | ret = KMessageBox::questionYesNoCancel(currentView, |
215 | i18n("The list \"") + | 215 | i18n("The list \"") + |
216 | docTitle + | 216 | docTitle + |
217 | i18n | 217 | i18n |
218 | ("\" has been modified.\n" | 218 | ("\" has been modified.\n" |
219 | "Do you want to save it?"), | 219 | "Do you want to save it?"), |
220 | i18n("save?")); | 220 | i18n("save?")); |
221 | if (ret == KMessageBox::Yes) { | 221 | if (ret == KMessageBox::Yes) { |
222 | return 0; | 222 | return 0; |
223 | } else if (ret == KMessageBox::No) { | 223 | } else if (ret == KMessageBox::No) { |
224 | return 1; | 224 | return 1; |
225 | } | 225 | } |
226 | #else | 226 | #else |
227 | ret = KMessageBox::warningYesNoCancel(currentView, | 227 | ret = KMessageBox::warningYesNoCancel(currentView, |
228 | i18n("The list \"") + | 228 | i18n("The list \"") + |
229 | docTitle + | 229 | docTitle + |
230 | i18n | 230 | i18n |
231 | ("\"\nhas been modified.\n" | 231 | ("\"\nhas been modified.\n" |
232 | "Do you want to save it?"), | 232 | "Do you want to save it?"), |
233 | i18n("save?")); | 233 | i18n("save?")); |
234 | if (ret == KMessageBox::Yes) { | 234 | if (ret == KMessageBox::Yes) { |
235 | return 0; | 235 | return 0; |
236 | } else if (ret == KMessageBox::No) { | 236 | } else if (ret == KMessageBox::No) { |
237 | return 1; | 237 | return 1; |
238 | } | 238 | } |
239 | 239 | ||
240 | #endif | 240 | #endif |
241 | 241 | ||
242 | // cancel | 242 | // cancel |
243 | return -1; | 243 | return -1; |
244 | } | 244 | } |
245 | 245 | ||
246 | bool PwMDocUi::saveDocUi(PwMDoc *doc) | 246 | bool PwMDocUi::saveDocUi(PwMDoc *doc) |
247 | { | 247 | { |
248 | PWM_ASSERT(doc); | 248 | PWM_ASSERT(doc); |
249 | doc->timer()->getLock(DocTimer::id_autoLockTimer); | 249 | doc->timer()->getLock(DocTimer::id_autoLockTimer); |
250 | if (doc->isDocEmpty()) { | 250 | if (doc->isDocEmpty()) { |
251 | KMessageBox::information(currentView, | 251 | KMessageBox::information(currentView, |
252 | i18n | 252 | i18n |
253 | ("Sorry, there's nothing to save.\n" | 253 | ("Sorry, there's nothing to save.\n" |
254 | "Please first add some passwords."), | 254 | "Please first add some passwords."), |
255 | i18n("nothing to do")); | 255 | i18n("nothing to do")); |
256 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 256 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
257 | return true; | 257 | return true; |
258 | } | 258 | } |
259 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression()); | 259 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression()); |
260 | if (ret == e_filename) { | 260 | if (ret == e_filename) { |
261 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 261 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
262 | return saveAsDocUi(doc); | 262 | return saveAsDocUi(doc); |
263 | } else if (ret == e_weakPw) { | 263 | } else if (ret == e_weakPw) { |
264 | KMessageBox::error(currentView, | 264 | KMessageBox::error(currentView, |
265 | i18n("Error: This is a weak password.\n" | 265 | i18n("Error: This is a weak password.\n" |
266 | "Please select another password."), | 266 | "Please select another password."), |
267 | i18n("weak password")); | 267 | i18n("weak password")); |
268 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 268 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
269 | return false; | 269 | return false; |
270 | } else if (ret == e_fileBackup) { | 270 | } else if (ret == e_fileBackup) { |
271 | KMessageBox::error(currentView, | 271 | KMessageBox::error(currentView, |
272 | i18n("Error: Couldn't make backup-file!"), | 272 | i18n("Error: Couldn't make backup-file!"), |
273 | i18n("backup failed")); | 273 | i18n("backup failed")); |
274 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 274 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
275 | return false; | 275 | return false; |
276 | } else if (ret == e_noPw || | ||
277 | ret == e_wrongPw || | ||
278 | ret == e_openFile) { | ||
279 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | ||
280 | return false; | ||
276 | } else if (ret != e_success) { | 281 | } else if (ret != e_success) { |
277 | KMessageBox::error(currentView, | 282 | KMessageBox::error(currentView, |
278 | i18n("Error: Couldn't write to file.\n" | 283 | i18n("Error: Couldn't write to file.\n" |
279 | "Please check if you have permission to\n" | 284 | "Please check if you have permission to\n" |
280 | "write to the file in that directory."), | 285 | "write to the file in that directory."), |
281 | i18n("error while writing")); | 286 | i18n("error while writing")); |
282 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 287 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
283 | return false; | 288 | return false; |
284 | } | 289 | } |
285 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 290 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
286 | return true; | 291 | return true; |
287 | } | 292 | } |
288 | 293 | ||
289 | bool PwMDocUi::saveAsDocUi(PwMDoc *doc) | 294 | bool PwMDocUi::saveAsDocUi(PwMDoc *doc) |
290 | { | 295 | { |
291 | PWM_ASSERT(doc); | 296 | PWM_ASSERT(doc); |
292 | doc->timer()->getLock(DocTimer::id_autoLockTimer); | 297 | doc->timer()->getLock(DocTimer::id_autoLockTimer); |
293 | if (doc->isDocEmpty()) { | 298 | if (doc->isDocEmpty()) { |
294 | KMessageBox::information(currentView, | 299 | KMessageBox::information(currentView, |
295 | i18n | 300 | i18n |
296 | ("Sorry, there's nothing to save.\n" | 301 | ("Sorry, there's nothing to save.\n" |
297 | "Please first add some passwords."), | 302 | "Please first add some passwords."), |
298 | i18n("nothing to do")); | 303 | i18n("nothing to do")); |
299 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 304 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
300 | return true; | 305 | return true; |
301 | } | 306 | } |
302 | #ifndef PWM_EMBEDDED | 307 | #ifndef PWM_EMBEDDED |
303 | QString fn(KFileDialog::getSaveFileName(QString::null, | 308 | QString fn(KFileDialog::getSaveFileName(QString::null, |
304 | i18n("*.pwm|PwManager Password file"), | 309 | i18n("*.pwm|PwManager Password file"), |
305 | currentView)); | 310 | currentView)); |
306 | #else | 311 | #else |
307 | QString fn = locateLocal( "data", KGlobal::getAppName() + "/*.pwm" ); | 312 | QString fn = locateLocal( "data", KGlobal::getAppName() + "/*.pwm" ); |
308 | fn = KFileDialog::getSaveFileName(fn, | 313 | fn = KFileDialog::getSaveFileName(fn, |
309 | i18n("password filename(*.pwm)"), | 314 | i18n("password filename(*.pwm)"), |
310 | currentView); | 315 | currentView); |
311 | 316 | ||
312 | #endif | 317 | #endif |
313 | if (fn == "") { | 318 | if (fn == "") { |
314 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 319 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
315 | return false; | 320 | return false; |
316 | } | 321 | } |
317 | if (fn.right(4) != ".pwm") | 322 | if (fn.right(4) != ".pwm") |
318 | fn += ".pwm"; | 323 | fn += ".pwm"; |
319 | 324 | ||
320 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); | 325 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); |
321 | if (ret != e_success) { | 326 | if (ret == e_noPw || |
327 | ret == e_wrongPw || | ||
328 | ret == e_openFile) { | ||
329 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | ||
330 | return false; | ||
331 | } else if (ret != e_success) { | ||
322 | KMessageBox::error(currentView, | 332 | KMessageBox::error(currentView, |
323 | i18n("Error: Couldn't write to file.\n" | 333 | i18n("Error: Couldn't write to file.\n" |
324 | "Please check if you have permission to\n" | 334 | "Please check if you have permission to\n" |
325 | "write to the file in that directory."), | 335 | "write to the file in that directory."), |
326 | i18n("error while writing")); | 336 | i18n("error while writing")); |
327 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 337 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
328 | return false; | 338 | return false; |
329 | } | 339 | } |
330 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 340 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
331 | return true; | 341 | return true; |
332 | } | 342 | } |
333 | 343 | ||
334 | bool PwMDocUi::openDocUi(PwMDoc *doc, | 344 | bool PwMDocUi::openDocUi(PwMDoc *doc, |
335 | QString filename, | 345 | QString filename, |
336 | bool openDeepLocked) | 346 | bool openDeepLocked) |
337 | { | 347 | { |
338 | if (filename.isEmpty()) | 348 | if (filename.isEmpty()) |
339 | { | 349 | { |
340 | #ifndef PWM_EMBEDDED | 350 | #ifndef PWM_EMBEDDED |
341 | filename = KFileDialog::getOpenFileName(QString::null, | 351 | filename = KFileDialog::getOpenFileName(QString::null, |
342 | i18n("*.pwm|PwManager Password file\n" | 352 | i18n("*.pwm|PwManager Password file\n" |
343 | "*|All files"), getCurrentView()); | 353 | "*|All files"), getCurrentView()); |
344 | #else | 354 | #else |
345 | filename = locateLocal( "data", KGlobal::getAppName() + "/*.pwm"); | 355 | filename = locateLocal( "data", KGlobal::getAppName() + "/*.pwm"); |
346 | filename = KFileDialog::getOpenFileName(filename, | 356 | filename = KFileDialog::getOpenFileName(filename, |
347 | i18n("password filename(*.pwm)"), getCurrentView()); | 357 | i18n("password filename(*.pwm)"), getCurrentView()); |
348 | #endif | 358 | #endif |
349 | } | 359 | } |
350 | if (filename.isEmpty()) | 360 | if (filename.isEmpty()) |
351 | goto cancelOpen; | 361 | goto cancelOpen; |
352 | PwMerror ret; | 362 | PwMerror ret; |
353 | while (true) { | 363 | while (true) { |
354 | int lockStat = -1; | 364 | int lockStat = -1; |
355 | if (openDeepLocked) { | 365 | if (openDeepLocked) { |
356 | lockStat = 2; | 366 | lockStat = 2; |
357 | } else { | 367 | } else { |
358 | if (conf()->confGlobUnlockOnOpen()) { | 368 | if (conf()->confGlobUnlockOnOpen()) { |
359 | lockStat = 0; | 369 | lockStat = 0; |
360 | } else { | 370 | } else { |
361 | lockStat = 1; | 371 | lockStat = 1; |
362 | } | 372 | } |
363 | } | 373 | } |
364 | ret = doc->openDoc(&filename, lockStat); | 374 | ret = doc->openDoc(&filename, lockStat); |
365 | //qDebug("pwmdocui::OpenDocui %i", ret); | 375 | //qDebug("pwmdocui::OpenDocui %i", ret); |
366 | if (ret != e_success) { | 376 | if (ret != e_success) { |
367 | if (ret == e_readFile || ret == e_openFile) { | 377 | if (ret == e_readFile || ret == e_openFile) { |
368 | KMessageBox::error(getCurrentView(), | 378 | KMessageBox::error(getCurrentView(), |
369 | i18n("Could not read file!") | 379 | i18n("Could not read file!") |
370 | + "\n" | 380 | + "\n" |
371 | + filename, | 381 | + filename, |
372 | i18n("file error")); | 382 | i18n("file error")); |
373 | goto cancelOpen; | 383 | goto cancelOpen; |
374 | } | 384 | } |
375 | if (ret == e_alreadyOpen) { | 385 | if (ret == e_alreadyOpen) { |
376 | KMessageBox::error(getCurrentView(), | 386 | KMessageBox::error(getCurrentView(), |
377 | i18n("This file is already open."), | 387 | i18n("This file is already open."), |
378 | i18n("already open")); | 388 | i18n("already open")); |
379 | goto cancelOpen; | 389 | goto cancelOpen; |
380 | } | 390 | } |
381 | if (ret == e_fileVer) { | 391 | if (ret == e_fileVer) { |
382 | KMessageBox::error(getCurrentView(), | 392 | KMessageBox::error(getCurrentView(), |
383 | i18n | 393 | i18n |
384 | ("File-version is not supported!\n" | 394 | ("File-version is not supported!\n" |
385 | "Did you create this file with an\nolder or newer version of PwM?"), | 395 | "Did you create this file with an\nolder or newer version of PwM?"), |
386 | i18n | 396 | i18n |
387 | ("incompatible version")); | 397 | ("incompatible version")); |
388 | goto cancelOpen; | 398 | goto cancelOpen; |
389 | } | 399 | } |
390 | if (ret == e_wrongPw) { | 400 | if (ret == e_wrongPw) { |
391 | continue; | 401 | continue; |
392 | } | 402 | } |
393 | if (ret == e_noPw) { | 403 | if (ret == e_noPw) { |
394 | goto cancelOpen; | 404 | goto cancelOpen; |
395 | } | 405 | } |
396 | if (ret == e_fileFormat) { | 406 | if (ret == e_fileFormat) { |
397 | KMessageBox::error(getCurrentView(), | 407 | KMessageBox::error(getCurrentView(), |
398 | i18n | 408 | i18n |
399 | ("Sorry, this file has not been recognized\n" | 409 | ("Sorry, this file has not been recognized\n" |
400 | "as a PwM Password file.\n" | 410 | "as a PwM Password file.\n" |
401 | "Probably you have selected the wrong file."), | 411 | "Probably you have selected the wrong file."), |
402 | i18n | 412 | i18n |
403 | ("no PwM password-file")); | 413 | ("no PwM password-file")); |
404 | goto cancelOpen; | 414 | goto cancelOpen; |
405 | } | 415 | } |
406 | if (ret == e_fileCorrupt) { | 416 | if (ret == e_fileCorrupt) { |
407 | KMessageBox::error(getCurrentView(), | 417 | KMessageBox::error(getCurrentView(), |
408 | i18n | 418 | i18n |
409 | ("File corrupt!\n" | 419 | ("File corrupt!\n" |
410 | "Maybe the media, you stored this file on,\n" | 420 | "Maybe the media, you stored this file on,\n" |
411 | "had bad sectors?"), | 421 | "had bad sectors?"), |
412 | i18n | 422 | i18n |
413 | ("checksum error")); | 423 | ("checksum error")); |
414 | goto cancelOpen; | 424 | goto cancelOpen; |
415 | } | 425 | } |
416 | } | 426 | } |
417 | break; | 427 | break; |
418 | } | 428 | } |
419 | return true; | 429 | return true; |
420 | 430 | ||
421 | cancelOpen: | 431 | cancelOpen: |
422 | return false; | 432 | return false; |
423 | } | 433 | } |
424 | 434 | ||
425 | QString PwMDocUi::string_defaultCategory() | 435 | QString PwMDocUi::string_defaultCategory() |
426 | { | 436 | { |
427 | return i18n("Default"); | 437 | return i18n("Default"); |
428 | } | 438 | } |
429 | 439 | ||
430 | QString PwMDocUi::string_locked() | 440 | QString PwMDocUi::string_locked() |
431 | { | 441 | { |
432 | return i18n("<LOCKED>"); | 442 | return i18n("<LOCKED>"); |
433 | } | 443 | } |
434 | 444 | ||
435 | QString PwMDocUi::string_deepLockedShort() | 445 | QString PwMDocUi::string_deepLockedShort() |
436 | { | 446 | { |
437 | return i18n("DEEP-LOCKED"); | 447 | return i18n("DEEP-LOCKED"); |
438 | } | 448 | } |
439 | 449 | ||
440 | QString PwMDocUi::string_deepLockedLong() | 450 | QString PwMDocUi::string_deepLockedLong() |
441 | { | 451 | { |
442 | return i18n("This file is DEEP-LOCKED!\n" | 452 | return i18n("This file is DEEP-LOCKED!\n" |
443 | "That means all data has been encrypted\n" | 453 | "That means all data has been encrypted\n" |
444 | "and written out to the file. If you want\n" | 454 | "and written out to the file. If you want\n" |
445 | "to see the entries, please UNLOCK the file.\n" | 455 | "to see the entries, please UNLOCK the file.\n" |
446 | "While unlocking, you will be prompted for the\n" | 456 | "While unlocking, you will be prompted for the\n" |
447 | "master-password or the key-card."); | 457 | "master-password or the key-card."); |
448 | } | 458 | } |
449 | 459 | ||
450 | QString PwMDocUi::string_defaultTitle() | 460 | QString PwMDocUi::string_defaultTitle() |
451 | { | 461 | { |
452 | return i18n("Untitled"); | 462 | return i18n("Untitled"); |
453 | } | 463 | } |
454 | 464 | ||
455 | #ifndef PWM_EMBEDDED | 465 | #ifndef PWM_EMBEDDED |
456 | #include "pwmdocui.moc" | 466 | #include "pwmdocui.moc" |
457 | #endif | 467 | #endif |