-rw-r--r-- | pwmanager/pwmanager/pwmdoc.h | 701 |
1 files changed, 701 insertions, 0 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h new file mode 100644 index 0000000..9650d55 --- a/dev/null +++ b/pwmanager/pwmanager/pwmdoc.h | |||
@@ -0,0 +1,701 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * copyright (C) 2003, 2004 by Michael Buesch * | ||
4 | * email: mbuesch@freenet.de * | ||
5 | * * | ||
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 * | ||
8 | * as published by the Free Software Foundation. * | ||
9 | * * | ||
10 | ***************************************************************************/ | ||
11 | |||
12 | /*************************************************************************** | ||
13 | * copyright (C) 2004 by Ulf Schenk | ||
14 | * This file is originaly based on version 2.0 of pwmanager | ||
15 | * and was modified to run on embedded devices that run microkde | ||
16 | * | ||
17 | * $Id$ | ||
18 | **************************************************************************/ | ||
19 | |||
20 | #ifndef __PWMDOC_H | ||
21 | #define __PWMDOC_H | ||
22 | |||
23 | #define PWM_FILE_VER (static_cast<char>(0x05)) | ||
24 | |||
25 | #define PWM_HASH_SHA1 (static_cast<char>(0x01)) | ||
26 | #define PWM_HASH_SHA256 (static_cast<char>(0x02)) | ||
27 | #define PWM_HASH_SHA384 (static_cast<char>(0x03)) | ||
28 | #define PWM_HASH_SHA512 (static_cast<char>(0x04)) | ||
29 | #define PWM_HASH_MD5 (static_cast<char>(0x05)) | ||
30 | #define PWM_HASH_RMD160 (static_cast<char>(0x06)) | ||
31 | #define PWM_HASH_TIGER (static_cast<char>(0x07)) | ||
32 | |||
33 | #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01)) | ||
34 | #define PWM_CRYPT_AES128(static_cast<char>(0x02)) | ||
35 | #define PWM_CRYPT_AES192(static_cast<char>(0x03)) | ||
36 | #define PWM_CRYPT_AES256(static_cast<char>(0x04)) | ||
37 | #define PWM_CRYPT_3DES (static_cast<char>(0x05)) | ||
38 | #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06)) | ||
39 | #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07)) | ||
40 | |||
41 | #define PWM_COMPRESS_NONE(static_cast<char>(0x00)) | ||
42 | #define PWM_COMPRESS_GZIP(static_cast<char>(0x01)) | ||
43 | #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02)) | ||
44 | |||
45 | #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0))) | ||
46 | #define FILE_ID_HEADER "PWM_PASSWORD_FILE" | ||
47 | |||
48 | |||
49 | #include "pwmexception.h" | ||
50 | #include "pwmdocui.h" | ||
51 | #include "configuration.h" | ||
52 | |||
53 | #include <qobject.h> | ||
54 | #include <qtimer.h> | ||
55 | #include <qdatetime.h> | ||
56 | |||
57 | #include <kprocess.h> | ||
58 | |||
59 | #ifndef PWM_EMBEDDED | ||
60 | #else | ||
61 | #include <kapplication.h> | ||
62 | #endif | ||
63 | |||
64 | #include <string> | ||
65 | #include <vector> | ||
66 | #include <utility> | ||
67 | |||
68 | using std::vector; | ||
69 | using std::string; | ||
70 | using std::pair; | ||
71 | |||
72 | /* used in findEntry() function */ | ||
73 | #define SEARCH_IN_DESC (1) | ||
74 | #define SEARCH_IN_NAME (1 << 1) | ||
75 | #define SEARCH_IN_PW (1 << 2) | ||
76 | #define SEARCH_IN_COMMENT(1 << 3) | ||
77 | #define SEARCH_IN_URL (1 << 4) | ||
78 | #define SEARCH_IN_LAUNCHER(1 << 5) | ||
79 | #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \ | ||
80 | SEARCH_IN_PW | SEARCH_IN_COMMENT| \ | ||
81 | SEARCH_IN_URL| SEARCH_IN_LAUNCHER) | ||
82 | |||
83 | /** document deeplocked. Data is out for lunch to disk */ | ||
84 | #define DOC_STAT_DEEPLOCKED (1) | ||
85 | /** encrypted document on disk is dirty. data has to go to disk. */ | ||
86 | #define DOC_STAT_DISK_DIRTY (1 << 1) | ||
87 | /** we are using a chipcard to encrypt the data */ | ||
88 | #define DOC_STAT_USE_CHIPCARD (1 << 2) | ||
89 | /** use "currentPw" to unlock. (This flag is set/unset by a timer) */ | ||
90 | #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3) | ||
91 | |||
92 | class PwMDoc; | ||
93 | class PwMView; | ||
94 | class QFile; | ||
95 | |||
96 | /* meta data for a PwMDataItem */ | ||
97 | struct PwMMetaData | ||
98 | { | ||
99 | PwMMetaData() | ||
100 | : updateInt (0) | ||
101 | { } | ||
102 | /** creation date of the PwMDataItem to which | ||
103 | * this meta data belongs. | ||
104 | */ | ||
105 | QDateTimecreate; | ||
106 | /** becomes valid on this date */ | ||
107 | QDateTimevalid; | ||
108 | /** expire date */ | ||
109 | QDateTimeexpire; | ||
110 | /** update date (last updated at this date) */ | ||
111 | QDateTimeupdate; | ||
112 | /** update interval (in minutes). Time since the | ||
113 | * last update to remind the user to update the item. | ||
114 | * 0 disables. | ||
115 | */ | ||
116 | unsigned long updateInt; | ||
117 | |||
118 | //US ENH: enhancements of the filestructure | ||
119 | /* each entry gets a unique id assigned */ | ||
120 | QString uniqueid; | ||
121 | |||
122 | |||
123 | void clear() | ||
124 | { | ||
125 | create = QDateTime(); | ||
126 | expire = QDateTime(); | ||
127 | update = QDateTime(); | ||
128 | updateInt = 0; | ||
129 | uniqueid = KApplication::randomString(8); | ||
130 | } | ||
131 | inline bool isValid() const | ||
132 | { | ||
133 | if (valid.isNull()) | ||
134 | return true; | ||
135 | return (valid < QDateTime::currentDateTime()); | ||
136 | } | ||
137 | inline bool isExpired() const | ||
138 | { | ||
139 | if (expire.isNull()) | ||
140 | return false; | ||
141 | return (expire < QDateTime::currentDateTime()); | ||
142 | } | ||
143 | inline bool isUpdateIntOver() const | ||
144 | { | ||
145 | if (updateInt == 0 || | ||
146 | update.isNull()) | ||
147 | return false; | ||
148 | QDateTime d(update); | ||
149 | return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); | ||
150 | } | ||
151 | }; | ||
152 | |||
153 | struct PwMDataItem | ||
154 | { | ||
155 | PwMDataItem() | ||
156 | : lockStat (true) | ||
157 | , listViewPos (-1) | ||
158 | , binary (false) | ||
159 | , rev (0) | ||
160 | { } | ||
161 | |||
162 | /** password description */ | ||
163 | stringdesc; | ||
164 | /** user-name */ | ||
165 | stringname; | ||
166 | /** the password itself */ | ||
167 | stringpw; | ||
168 | /** some comment */ | ||
169 | stringcomment; | ||
170 | /** an URL string */ | ||
171 | stringurl; | ||
172 | /** launcher. Can be executed as a system() command */ | ||
173 | stringlauncher; | ||
174 | /** locking status. If locked (true), pw is not emitted through getEntry() */ | ||
175 | boollockStat; | ||
176 | /** position of this item in main "list-view" | ||
177 | * If -1, the position is not yet specified and should be appended to the list | ||
178 | */ | ||
179 | intlistViewPos; | ||
180 | /** does this entry contain binary data? */ | ||
181 | bool binary; | ||
182 | /** meta data for this data item. */ | ||
183 | PwMMetaData meta; | ||
184 | /** data revision counter. This counter can be used | ||
185 | * to easily, efficiently determine if this data item | ||
186 | * has changed since some time. | ||
187 | * This counter is incremented on every update. | ||
188 | */ | ||
189 | unsigned int rev; | ||
190 | |||
191 | void clear(bool clearMeta = true) | ||
192 | { | ||
193 | /* NOTE: Don't use .clear() here to be | ||
194 | * backward compatible with gcc-2 (Debian Woody) | ||
195 | */ | ||
196 | desc = ""; | ||
197 | name = ""; | ||
198 | pw = ""; | ||
199 | comment = ""; | ||
200 | url = ""; | ||
201 | launcher = ""; | ||
202 | lockStat = true; | ||
203 | listViewPos = -1; | ||
204 | binary = false; | ||
205 | if (clearMeta) | ||
206 | meta.clear(); | ||
207 | } | ||
208 | }; | ||
209 | |||
210 | struct PwMCategoryItem | ||
211 | { | ||
212 | /** all PwMDataItems (all passwords) within this category */ | ||
213 | vector<PwMDataItem>d; | ||
214 | /** category name/description */ | ||
215 | string name; | ||
216 | |||
217 | void clear() | ||
218 | { | ||
219 | d.clear(); | ||
220 | name = ""; | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | /** "Function Object" for sort()ing PwMDataItem::listViewPos */ | ||
225 | class dta_lvp_greater | ||
226 | { | ||
227 | public: | ||
228 | bool operator() (const pair<unsigned int, unsigned int> &d1, | ||
229 | const pair<unsigned int, unsigned int> &d2) | ||
230 | { | ||
231 | return d1.second > d2.second; | ||
232 | } | ||
233 | }; | ||
234 | |||
235 | /** list of PwMDoc documents and it's IDs */ | ||
236 | class PwMDocList | ||
237 | { | ||
238 | public: | ||
239 | struct listItem | ||
240 | { | ||
241 | /** document filename (known as ID, here) */ | ||
242 | string docId; | ||
243 | /** pointer to the document class */ | ||
244 | PwMDoc *doc; | ||
245 | }; | ||
246 | |||
247 | PwMDocList() {} | ||
248 | |||
249 | /** add a new item to the list */ | ||
250 | void add(PwMDoc *doc, const string &id); | ||
251 | /** changes the contents of an existing item */ | ||
252 | void edit(PwMDoc *doc, const string &newId); | ||
253 | /** remove the given item */ | ||
254 | void del(PwMDoc *doc); | ||
255 | /** get the item at index */ | ||
256 | listItem getAt(int index) | ||
257 | { return docList[index]; } | ||
258 | /** find an entry with this id */ | ||
259 | bool find(const string &id, listItem *ret = 0); | ||
260 | /** returns a copy of the list */ | ||
261 | const vector<listItem>* getList() const | ||
262 | { return &docList; } | ||
263 | |||
264 | |||
265 | /** returns a new unique number to extend the name of | ||
266 | * an unnamed document. | ||
267 | */ | ||
268 | static unsigned int getNewUnnamedNumber() | ||
269 | { return unnamedDocCnt++; } | ||
270 | |||
271 | protected: | ||
272 | /* Hm, I think we shouldn't really use a "list" here, should we? | ||
273 | * So I decided to actually use a vector. | ||
274 | */ | ||
275 | vector<listItem> docList; | ||
276 | /** This value is used to get a new number for yet unnamed | ||
277 | * documents. It is incremented on every request. So it's | ||
278 | * theoretically possible to overflow it, but... :) | ||
279 | */ | ||
280 | static unsigned int unnamedDocCnt; | ||
281 | }; | ||
282 | |||
283 | /** implements timers for the document */ | ||
284 | class DocTimer : public QObject | ||
285 | { | ||
286 | Q_OBJECT | ||
287 | public: | ||
288 | enum TimerIDs | ||
289 | { | ||
290 | id_mpwTimer, | ||
291 | id_autoLockTimer, | ||
292 | id_metaCheckTimer | ||
293 | }; | ||
294 | |||
295 | public: | ||
296 | DocTimer(PwMDoc *_doc); | ||
297 | ~DocTimer(); | ||
298 | |||
299 | /** start the timer */ | ||
300 | void start(TimerIDs timer); | ||
301 | /** stop the timer */ | ||
302 | void stop(TimerIDs timer); | ||
303 | /** get the lock for a timer. | ||
304 | * This lock is a recursive lock. When a lock is | ||
305 | * held, the timer will be stopped and timeout is | ||
306 | * guaranteed to not happen | ||
307 | */ | ||
308 | void getLock(TimerIDs timer); | ||
309 | /** put a recursive timer lock */ | ||
310 | void putLock(TimerIDs timer); | ||
311 | |||
312 | protected slots: | ||
313 | /** timeout slot for the mpw timer */ | ||
314 | void mpwTimeout(); | ||
315 | /** timeout slot for the autoLock timer */ | ||
316 | void autoLockTimeout(); | ||
317 | /** timeout slot for the metaCheck timer */ | ||
318 | void metaCheckTimeout(); | ||
319 | |||
320 | protected: | ||
321 | /** pointer to the document associated with this timer. */ | ||
322 | PwMDoc *doc; | ||
323 | /** timer object for mpw timer */ | ||
324 | QTimer *mpwTimer; | ||
325 | /** timer object for the autoLock timer */ | ||
326 | QTimer *autoLockTimer; | ||
327 | /** timer object for the metaCheck timer */ | ||
328 | QTimer *metaCheckTimer; | ||
329 | /** lock counter for the mpw timer */ | ||
330 | unsigned int mpwLock; | ||
331 | /** lock counter for the autoLock timer */ | ||
332 | unsigned int autoLockLock; | ||
333 | /** lock counter for the metaCheck timer */ | ||
334 | unsigned int metaCheckLock; | ||
335 | }; | ||
336 | |||
337 | /** Document class for PwM */ | ||
338 | class PwMDoc : public PwMDocUi | ||
339 | { | ||
340 | Q_OBJECT | ||
341 | friend class DocTimer; | ||
342 | |||
343 | public: | ||
344 | /** construtor */ | ||
345 | PwMDoc(QObject* parent = 0, const char *name = 0); | ||
346 | /** destructor */ | ||
347 | ~PwMDoc(); | ||
348 | |||
349 | /** returns a pointer to a list of all open documents */ | ||
350 | static PwMDocList* getOpenDocList() | ||
351 | { return &openDocList; } | ||
352 | |||
353 | /** flag document dirty. dta changed */ | ||
354 | void flagDirty() | ||
355 | { | ||
356 | setDocStatFlag(DOC_STAT_DISK_DIRTY); | ||
357 | emitDataChanged(this); | ||
358 | } | ||
359 | /** modified? */ | ||
360 | bool isDirty() | ||
361 | { return getDocStatFlag(DOC_STAT_DISK_DIRTY); } | ||
362 | /** save document to disk */ | ||
363 | PwMerror saveDoc(char compress, const QString *file = 0); | ||
364 | /** read document from file. | ||
365 | * "openLocked is must be set to either of these values: | ||
366 | * 0 == open with all entries unlocked | ||
367 | * 1 == open with all entries locked | ||
368 | * 2 == open deep-locked | ||
369 | */ | ||
370 | PwMerror openDoc(const QString *file, int openLocked); | ||
371 | /** export document to ascii-textfile */ | ||
372 | PwMerror exportToText(const QString *file); | ||
373 | /** export document to gpasman / kpasman file */ | ||
374 | PwMerror exportToGpasman(const QString *file); | ||
375 | /** import document from ascii-textfile */ | ||
376 | PwMerror importFromText(const QString *file, int format = -1); | ||
377 | /** import document from gpasman / kpasman file */ | ||
378 | PwMerror importFromGpasman(const QString *file); | ||
379 | /** add new entry */ | ||
380 | PwMerror addEntry(const QString &category, PwMDataItem *d, | ||
381 | bool dontFlagDirty = false, bool updateMeta = true); | ||
382 | /** add new category. This function doesn't flag the document dirty! */ | ||
383 | PwMerror addCategory(const QString &category, unsigned int *categoryIndex, | ||
384 | bool checkIfExist = true); | ||
385 | /** rename an existing category */ | ||
386 | bool renameCategory(const QString &category, const QString &newName); | ||
387 | /** rename an existing category */ | ||
388 | bool renameCategory(unsigned int category, const QString &newName, | ||
389 | bool dontFlagDirty = false); | ||
390 | /** delete an existing category */ | ||
391 | bool delCategory(const QString &category); | ||
392 | /** delete an existing category */ | ||
393 | bool delCategory(unsigned int category, bool dontFlagDirty = false); | ||
394 | /** returns a list of all category-names */ | ||
395 | void getCategoryList(vector<string> *list); | ||
396 | /** returns a list of all category-names */ | ||
397 | void getCategoryList(QStringList *list); | ||
398 | /** returns a list of all entry-descs in the given category */ | ||
399 | void getEntryList(const QString &category, QStringList *list); | ||
400 | /** returns a list of all entry-descs in the given category */ | ||
401 | void getEntryList(const QString &category, vector<string> *list); | ||
402 | /** returns a list of all entry-descs in the given category */ | ||
403 | void getEntryList(unsigned int category, vector<string> *list); | ||
404 | /** returns a list of all entry-descs in the given category */ | ||
405 | void getEntryList(unsigned int category, QStringList *list); | ||
406 | /** delete entry */ | ||
407 | bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false); | ||
408 | /** delete entry */ | ||
409 | bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false); | ||
410 | /** edit entry */ | ||
411 | bool editEntry(const QString &oldCategory, const QString &newCategory, | ||
412 | unsigned int index, PwMDataItem *d, bool updateMeta = true); | ||
413 | /** edit entry */ | ||
414 | bool editEntry(unsigned int oldCategory, const QString &newCategory, | ||
415 | unsigned int index, PwMDataItem *d, bool updateMeta = true); | ||
416 | /** finds the category with the "name" and return it's index */ | ||
417 | bool findCategory(const QString &name, unsigned int *index); | ||
418 | /** search for an entry "find" and check while searching only for | ||
419 | * the data-fields specified by "searchIn". To set the "searchIn" | ||
420 | * value, we may use one or more of the SEARCH_IN_* defines at | ||
421 | * the top of this header-file. It returns the positions of all | ||
422 | * matched entries in "foundPositions". If "breakAfterFound" is true, | ||
423 | * the function terminates after the first occurence of the entry | ||
424 | * and doesn't go on searching. So foundPositions->size() is never | ||
425 | * > 1 if breakAfterFound is true. | ||
426 | */ | ||
427 | void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, | ||
428 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, | ||
429 | bool caseSensitive = true, bool exactWordMatch = true, | ||
430 | bool sortByLvp = false); | ||
431 | /** see the above funtion. This function allows to set the category by name. */ | ||
432 | void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, | ||
433 | vector<unsigned int> *foundPositions, bool breakAfterFound = false, | ||
434 | bool caseSensitive = true, bool exactWordMatch = true, | ||
435 | bool sortByLvp = false); | ||
436 | /** returns number of entries */ | ||
437 | unsigned int numEntries(const QString &category); | ||
438 | unsigned int numEntries(unsigned int category) | ||
439 | { return dta[category].d.size(); } | ||
440 | /** returns number of categories */ | ||
441 | unsigned int numCategories() | ||
442 | { return dta.size(); } | ||
443 | /** returns the name of the category at "index" */ | ||
444 | const string* getCategory(unsigned int index) | ||
445 | { return (&(dta[index].name)); } | ||
446 | /** returns the data of item at "index". | ||
447 | * It unlocks the entry if it's locked and unlockIfLocked is true. | ||
448 | * If the entry is locked, but unlockIfLocked is false, it'll not return | ||
449 | * the pw. | ||
450 | */ | ||
451 | bool getEntry(const QString &category, unsigned int index, | ||
452 | PwMDataItem *d, bool unlockIfLocked = false); | ||
453 | bool getEntry(unsigned int category, unsigned int index, | ||
454 | PwMDataItem *d, bool unlockIfLocked = false); | ||
455 | /** returns the comment-string by looking at the category | ||
456 | * and the listViewPos | ||
457 | */ | ||
458 | PwMerror getCommentByLvp(const QString &category, int listViewPos, | ||
459 | string *foundComment); | ||
460 | /** checks if a password is already available. (currentPw) */ | ||
461 | bool isPwAvailable() | ||
462 | { return (currentPw != ""); } | ||
463 | /** un/lock entry at "index". If needed, ask for password. */ | ||
464 | bool lockAt(const QString &category, unsigned int index, | ||
465 | bool lock = true); | ||
466 | bool lockAt(unsigned int category, unsigned int index, | ||
467 | bool lock = true); | ||
468 | /** returns the lock-status at "index" */ | ||
469 | bool isLocked(const QString &category, unsigned int index); | ||
470 | bool isLocked(unsigned int category, unsigned int index) | ||
471 | { return dta[category].d[index].lockStat; } | ||
472 | /** returns the deeplock status */ | ||
473 | bool isDeepLocked() | ||
474 | { return getDocStatFlag(DOC_STAT_DEEPLOCKED); } | ||
475 | /** (un)lock all entries */ | ||
476 | bool lockAll(bool lock); | ||
477 | /** unlocks all entries tempoarly. | ||
478 | * 1st NOTE: Be very careful with this function! :) | ||
479 | * 2nd NOTE: After you have called unlockAll_Tempoary(); , | ||
480 | * please DON'T forget to call unlockAll_Tempoary(true); | ||
481 | * _before_ the user (or someone else) is able to change | ||
482 | * the document! | ||
483 | * 3rd NOTE: Please DON'T change "dta" while the data is tempoary | ||
484 | * unlocked! This will cause corruption. | ||
485 | */ | ||
486 | bool unlockAll_tempoary(bool revert = false); | ||
487 | /** deep-(un)locks the document. | ||
488 | * deep-locking writes all data to the file, deletes all data | ||
489 | * in memory, but doesn't close the document. | ||
490 | * deep-locking is only available, if the user previously saved | ||
491 | * the doc to a file (with a password). | ||
492 | * If "saveToFile" is false, it does NOT write the data to the file! | ||
493 | */ | ||
494 | PwMerror deepLock(bool lock = true, bool saveToFile = true); | ||
495 | /** is unlockable without pw? */ | ||
496 | bool unlockWoPw() | ||
497 | { return getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); } | ||
498 | /** get the "currentPassword" */ | ||
499 | const QString& getCurrentPw() | ||
500 | { return currentPw; } | ||
501 | /** open a window and request the user to change the mpw */ | ||
502 | void changeCurrentPw(); | ||
503 | /** set the "listViewPos" variable of "dta" */ | ||
504 | void setListViewPos(const QString &category, unsigned int index, | ||
505 | int pos); | ||
506 | /** set the "listViewPos" variable of "dta" */ | ||
507 | void setListViewPos(unsigned int category, unsigned int index, | ||
508 | int pos); | ||
509 | /** get the "listViewPos" variable of "dta" */ | ||
510 | int getListViewPos(const QString &category, unsigned int index); | ||
511 | /** set the maximum number of entries allowed */ | ||
512 | void setMaxNumEntries(unsigned int num = DEFAULT_MAX_ENTRIES) | ||
513 | { maxEntries = num; } | ||
514 | /** get the maximum number of entries allowed */ | ||
515 | unsigned int getMaxNumEntries() | ||
516 | { return maxEntries; } | ||
517 | /** ensure all listViewPos of all dta items are set. (are ! -1). | ||
518 | * If there are some undefined entries, add them to the end of | ||
519 | * the listViewPos(itions). */ | ||
520 | void ensureLvp(); | ||
521 | /** execute the "launcher" of this entry */ | ||
522 | bool execLauncher(const QString &category, unsigned int entryIndex); | ||
523 | /** see above */ | ||
524 | bool execLauncher(unsigned int category, unsigned int entryIndex); | ||
525 | /** open a browser with the URL-section of the given entry */ | ||
526 | bool goToURL(const QString &category, unsigned int entryIndex); | ||
527 | /** see above */ | ||
528 | bool goToURL(unsigned int category, unsigned int entryIndex); | ||
529 | /** returns true if there is no entry present in the document. | ||
530 | * Note: The "default" Category is present everytime, so | ||
531 | * it's checked for it's entries. | ||
532 | */ | ||
533 | bool isDocEmpty() | ||
534 | { | ||
535 | if (numCategories() > 1) | ||
536 | return false; | ||
537 | if (numEntries(0)) | ||
538 | return false; | ||
539 | return true; | ||
540 | } | ||
541 | /** returns the filename of this doc */ | ||
542 | const QString& getFilename() | ||
543 | { return filename; } | ||
544 | /** returns the title of the doc */ | ||
545 | QString getTitle(); | ||
546 | /** sets the list-view-pointer hold in the doc */ | ||
547 | void setListViewPointer(PwMView *_listView) | ||
548 | { listView = _listView; } | ||
549 | /** returns the list-view-pointer */ | ||
550 | PwMView * getListViewPointer() | ||
551 | { return listView; } | ||
552 | /** try to delete the doc. The user may be asked to save | ||
553 | * the data. The user may cancel the whole operation. | ||
554 | * false is returned, then. | ||
555 | */ | ||
556 | bool tryDelete(); | ||
557 | /** is the doc deleted? (with tryDelete() ) */ | ||
558 | bool isDeleted() | ||
559 | { return deleted; } | ||
560 | /** returns the document timer object */ | ||
561 | DocTimer * timer() | ||
562 | { return _timer; } | ||
563 | /** get a lock on the dataChanged signal. | ||
564 | * If someone is holding a lock, the signal is not emitted. | ||
565 | */ | ||
566 | void getDataChangedLock() | ||
567 | { ++dataChangedLock; } | ||
568 | /** put the dataChanged lock */ | ||
569 | void putDataChangedLock() | ||
570 | { --dataChangedLock; } | ||
571 | /** returns the revision count of the item at cat/index */ | ||
572 | unsigned int getEntryRevCnt(unsigned int category, unsigned int index) | ||
573 | { return dta[category].d[index].rev; } | ||
574 | /** returns a const pointer to the entries meta */ | ||
575 | const PwMMetaData * getEntryMeta(unsigned int category, unsigned int index) | ||
576 | { return &(dta[category].d[index].meta); } | ||
577 | /** is the entry at "category" "index" a binary entry? */ | ||
578 | bool isBinEntry(unsigned int category, unsigned int index) | ||
579 | { return dta[category].d[index].binary; } | ||
580 | |||
581 | public slots: | ||
582 | /** wrapper for PwMTray */ | ||
583 | void _deepUnlock(); | ||
584 | |||
585 | signals: | ||
586 | /** the data of the document has changed and must be updated | ||
587 | * in all views. | ||
588 | * NOTE: use emitDataChanged(PwMDoc *document) to emit this signal! | ||
589 | */ | ||
590 | void dataChanged(PwMDoc *document); | ||
591 | /** the document class is going to close. This signal may be | ||
592 | * used to nofify all views, that the user closed the document, | ||
593 | * so the views can go down, too. | ||
594 | */ | ||
595 | void docClosed(PwMDoc *document); | ||
596 | /** somebody just opened the document */ | ||
597 | void docOpened(PwMDoc *document); | ||
598 | /** this document object just got created */ | ||
599 | void docCreated(PwMDoc *document); | ||
600 | |||
601 | public: | ||
602 | /** emit the dataChanged signal after checking for a lock */ | ||
603 | void emitDataChanged(PwMDoc *document) | ||
604 | { | ||
605 | if (!dataChangedLock) | ||
606 | emit dataChanged(document); | ||
607 | } | ||
608 | |||
609 | protected: | ||
610 | /** current file for this doc */ | ||
611 | QString filename; | ||
612 | /** holds all data */ | ||
613 | vector<PwMCategoryItem> dta; | ||
614 | /** maximum number of entries */ | ||
615 | unsigned int maxEntries; | ||
616 | /** currently used password to encrypt data */ | ||
617 | QString currentPw; | ||
618 | /** current global document status flags */ | ||
619 | unsigned int curDocStat; | ||
620 | /** browser process for goToURL() */ | ||
621 | KProcess browserProc; | ||
622 | /** pointer to the list-view, using this document. | ||
623 | * As there can only be one list-view per doc, we | ||
624 | * don't need a list here. | ||
625 | */ | ||
626 | PwMView *listView; | ||
627 | /** unnamedNum is used to store the "unnamed counter" | ||
628 | * for this document, while it's unnamed. If it's 0, | ||
629 | * we have to get a new unique one. | ||
630 | */ | ||
631 | unsigned int unnamedNum; | ||
632 | /** is this doc going to be deleted (executing in destructor context) */ | ||
633 | bool deleted; | ||
634 | /** document timer */ | ||
635 | DocTimer *_timer; | ||
636 | /** lock counter for the "dataChanged" signal */ | ||
637 | unsigned int dataChangedLock; | ||
638 | |||
639 | /** list of all open documents */ | ||
640 | static PwMDocList openDocList; | ||
641 | |||
642 | protected: | ||
643 | /** serialize "dta" and return it in "d". */ | ||
644 | bool serializeDta(string *d); | ||
645 | /** de-serialize "d" and overwrite "dta" */ | ||
646 | bool deSerializeDta(const string *d, bool entriesLocked); | ||
647 | /** write header to file */ | ||
648 | PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress, | ||
649 | QString *pw, QFile *f); | ||
650 | /** write data-hash to file */ | ||
651 | PwMerror writeDataHash(char dataHash, string *d, QFile *f); | ||
652 | /** check header. Read header info and verify key-hash and filever. | ||
653 | * returns length of header in "headerLength" */ | ||
654 | PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress, | ||
655 | unsigned int *headerLength, char *dataHashType, | ||
656 | string *dataHash, QFile *f); | ||
657 | /** check the data-hash */ | ||
658 | PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream); | ||
659 | /** encrypt data "d" and write to "filename" */ | ||
660 | PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo); | ||
661 | /** read data from file beginning at "pos", decrypt and return it */ | ||
662 | PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f); | ||
663 | /** compress the data */ | ||
664 | bool compressDta(string *d, char algo); | ||
665 | /** uncompress the data */ | ||
666 | bool decompressDta(string *d, char algo); | ||
667 | /** internal import function for a text-file generated by PwM. | ||
668 | * If this is not a valid PwM-exported file, it returns e_fileFormat */ | ||
669 | PwMerror importText_PwM(const QString *file); | ||
670 | /** PwM-text-import helper function to extract the name/pw/comment out | ||
671 | * of one entry-line */ | ||
672 | bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out); | ||
673 | /** compare two strings */ | ||
674 | bool compareString(const string &s1, const string &s2, bool caseSensitive, | ||
675 | bool exactWordMatch); | ||
676 | /** clears all document-data */ | ||
677 | void clearDoc(); | ||
678 | /** delete all empty categories */ | ||
679 | void delAllEmptyCat(bool dontFlagDirty); | ||
680 | /** set a document status flag */ | ||
681 | void setDocStatFlag(unsigned int statFlag) | ||
682 | { curDocStat |= statFlag; } | ||
683 | /** unset a document status flag */ | ||
684 | void unsetDocStatFlag(unsigned int statFlag) | ||
685 | { curDocStat &= ~statFlag; } | ||
686 | /** get a document status flag */ | ||
687 | bool getDocStatFlag(unsigned int statFlag) const | ||
688 | { return (curDocStat & statFlag); } | ||
689 | /** set the "currentPassword" */ | ||
690 | void setCurrentPw(const QString &pw) | ||
691 | { | ||
692 | currentPw = pw; | ||
693 | setDocStatFlag(DOC_STAT_DISK_DIRTY); | ||
694 | } | ||
695 | /** make a backup-copy of the given file */ | ||
696 | bool backupFile(const QString &filePath); | ||
697 | /** copy a file from src to dst */ | ||
698 | bool copyFile(const QString &src, const QString &dst); | ||
699 | }; | ||
700 | |||
701 | #endif | ||