Initial commit
[keepassx] / src / Kdb3Database.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2007 by Tarek Saidi                                *
3  *   tarek.saidi@arcor.de                                                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; version 2 of the License.               *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19
20 #ifndef _STD_DATABASE_H_
21 #define _STD_DATABASE_H_
22
23 #include <QThread>
24
25 #define DB_HEADER_SIZE  124
26 #define PWM_DBSIG_1             0x9AA2D903
27 #define PWM_DBSIG_2     0xB54BFB65
28 #define PWM_DBVER_DW    0x00030002
29 #define PWM_FLAG_SHA2                   1
30 #define PWM_FLAG_RIJNDAEL               2
31 #define PWM_FLAG_ARCFOUR                4
32 #define PWM_FLAG_TWOFISH                8
33 #define PWM_STD_KEYENCROUNDS    6000
34
35 void memcpyFromLEnd32(quint32* dst,const char* src);
36 void memcpyFromLEnd16(quint16* dst,const char* src);
37 void memcpyToLEnd32(char* src,const quint32* dst);
38 void memcpyToLEnd16(char* src,const quint16* dst);
39
40 //! Implementation of the standard KeePassX database.
41 class Kdb3Database:public ICustomIcons,public IDatabase, public IKdbSettings{
42 Q_OBJECT
43 public:
44         class StdGroup;
45         class StdEntry;
46         class EntryHandle:public IEntryHandle{
47
48                 friend class Kdb3Database;
49                 public:
50                         EntryHandle(Kdb3Database* db);
51                         virtual void setImage(const quint32& ImageID);
52                         virtual void setTitle(const QString& Title);
53                         virtual void setUrl(const QString& URL);
54                         virtual void setUsername(const QString& Username);
55                         virtual void setPassword(const SecString& Password);
56                         virtual void setComment(const QString& Comment);
57                         virtual void setBinaryDesc(const QString& BinaryDesc);
58                         virtual void setCreation(const KpxDateTime& Creation);
59                         virtual void setLastMod(const KpxDateTime& LastMod);
60                         virtual void setLastAccess(const KpxDateTime& LastAccess);
61                         virtual void setExpire(const KpxDateTime& Expire);
62                         virtual void setBinary(const QByteArray& BinaryData);
63                         virtual KpxUuid uuid()const;
64                         virtual IGroupHandle* group()const;
65                         virtual quint32 image()const;
66                         virtual int visualIndex() const;
67                         virtual void setVisualIndex(int i);
68                         virtual void setVisualIndexDirectly(int i);
69                         virtual QString title()const;
70                         virtual QString url()const;
71                         virtual QString username()const;
72                         virtual SecString password()const;
73                         virtual QString comment()const;
74                         virtual QString binaryDesc()const;
75                         virtual KpxDateTime creation()const;
76                         virtual KpxDateTime lastMod()const;
77                         virtual KpxDateTime lastAccess()const;
78                         virtual KpxDateTime expire()const;
79                         virtual QByteArray binary()const;
80                         virtual quint32 binarySize()const;
81                         virtual QString friendlySize()const;
82                         virtual bool isValid() const;
83                         virtual CEntry data()const;
84                 private:
85                         void invalidate(){valid=false;}
86                         bool valid;
87                         //KpxUuid Uuid; ???
88                         Kdb3Database* pDB;
89                         StdEntry* Entry;
90         };
91
92         class GroupHandle:public IGroupHandle{
93                 friend class Kdb3Database;
94                 GroupHandle(Kdb3Database* db);
95                 public:
96                         virtual void setTitle(const QString& Title);
97                         virtual void setImage(const quint32& ImageId);
98                         virtual QString title();
99                         virtual quint32 image();
100                         virtual bool isValid();
101                         virtual IGroupHandle* parent();
102                         virtual QList<IGroupHandle*> children();
103                         virtual int index();
104                         //virtual void setIndex(int index);
105                         virtual int level();
106                         virtual bool expanded();
107                         virtual void setExpanded(bool IsExpanded);
108                 private:
109                         void invalidate(){valid=false;}
110                         bool valid;
111                         StdGroup* Group;
112                         Kdb3Database* pDB;
113         };
114
115         friend class EntryHandle;
116         friend class GroupHandle;
117
118         class StdEntry:public CEntry{
119                 public:
120                                 quint16 Index;
121                                 EntryHandle* Handle;
122                                 StdGroup* Group;
123         };
124
125         class StdGroup:public CGroup{
126                 public:
127                         StdGroup():CGroup(){};
128                         StdGroup(const CGroup&);
129                         quint16 Index;
130                         StdGroup* Parent;
131                         GroupHandle* Handle;
132                         QList<StdGroup*> Children;
133                         QList<StdEntry*> Entries;
134         };
135
136         Kdb3Database();
137         virtual ~Kdb3Database(){};
138         virtual bool load(QString identifier, bool readOnly);
139         virtual bool save();
140         virtual bool close();
141         virtual void create();
142         virtual int numEntries();
143         virtual int numGroups();
144         virtual QString getError();
145         virtual bool isKeyError();
146         virtual void cleanUpHandles();
147         virtual QPixmap& icon(int index);
148         virtual int numIcons();
149         virtual void addIcon(const QPixmap& icon);
150         virtual void removeIcon(int index);
151         virtual void replaceIcon(int index,const QPixmap& icon);
152         virtual int builtinIcons(){return BUILTIN_ICONS;};
153         virtual QList<IEntryHandle*> search(IGroupHandle* Group,const QString& SearchString, bool CaseSensitve, bool RegExp,bool Recursive,bool* Fields);
154         virtual QFile* file(){return File;}
155         virtual bool changeFile(const QString& filename);
156         virtual void setCryptAlgorithm(CryptAlgorithm algo){Algorithm=algo;}
157         virtual CryptAlgorithm cryptAlgorithm(){return Algorithm;}
158         virtual unsigned int keyTransfRounds(){return KeyTransfRounds;}
159         virtual void setKeyTransfRounds(unsigned int rounds){KeyTransfRounds=rounds;}
160         virtual bool setKey(const QString& password, const QString& keyfile);
161         virtual bool setPasswordKey(const QString& password);
162         virtual bool setFileKey(const QString& filename);
163         virtual bool setCompositeKey(const QString& password,const QString& filename);
164
165         virtual QList<IEntryHandle*> entries();
166         virtual QList<IEntryHandle*> entries(IGroupHandle* Group);
167         virtual QList<IEntryHandle*> entriesSortedStd(IGroupHandle* Group);
168         virtual QList<IEntryHandle*> expiredEntries();
169
170         virtual IEntryHandle* cloneEntry(const IEntryHandle* entry);
171         virtual void deleteEntry(IEntryHandle* entry);
172         virtual void deleteEntries(QList<IEntryHandle*> entries);
173         virtual IEntryHandle* newEntry(IGroupHandle* group);
174         virtual IEntryHandle* addEntry(const CEntry* NewEntry, IGroupHandle* group);
175         virtual void moveEntry(IEntryHandle* entry, IGroupHandle* group);
176         virtual void deleteLastEntry();
177
178
179         virtual QList<IGroupHandle*> groups();
180         virtual QList<IGroupHandle*> sortedGroups();
181         virtual void deleteGroup(IGroupHandle* group);
182         virtual void moveGroup(IGroupHandle* Group,IGroupHandle* NewParent,int Position);
183         virtual IGroupHandle* addGroup(const CGroup* Group,IGroupHandle* Parent);
184         virtual IGroupHandle* backupGroup(bool create=false);
185         virtual bool isParent(IGroupHandle* parent, IGroupHandle* child);
186         
187         virtual void generateMasterKey();
188         //virtual IDatabase* groupToNewDb(IGroupHandle* group);
189         
190         inline bool hasPasswordEncodingChanged() { return passwordEncodingChanged; };
191
192 private:
193         bool loadReal(QString filename, bool readOnly, bool differentEncoding);
194         QDateTime dateFromPackedStruct5(const unsigned char* pBytes);
195         void dateToPackedStruct5(const QDateTime& datetime, unsigned char* dst);
196         bool isMetaStream(StdEntry& Entry);
197         bool parseMetaStream(const StdEntry& Entry);
198         void parseCustomIconsMetaStream(const QByteArray& data);
199         void parseCustomIconsMetaStreamV3(const QByteArray& data);
200         void parseGroupTreeStateMetaStream(const QByteArray& data);
201         void createCustomIconsMetaStream(StdEntry* e);
202         void createGroupTreeStateMetaStream(StdEntry* e);
203         bool readEntryField(StdEntry* entry, quint16 FieldType, quint32 FieldSize, quint8 *pData);
204         bool readGroupField(StdGroup* group,QList<quint32>& Levels,quint16 FieldType, quint8 *pData);
205         bool createGroupTree(QList<quint32>& Levels);
206         void createHandles();
207         void invalidateHandle(StdEntry* entry);
208         bool convHexToBinaryKey(char* HexKey, char* dst);
209         quint32 getNewGroupId();
210         void serializeEntries(QList<StdEntry>& EntryList,char* buffer,unsigned int& pos);
211         void serializeGroups(char* buffer,unsigned int& pos);
212         void appendChildrenToGroupList(QList<StdGroup*>& list,StdGroup& group);
213         void appendChildrenToGroupList(QList<IGroupHandle*>& list,StdGroup& group);
214         bool searchStringContains(const QString& search, const QString& string,bool Cs, bool RegExp);
215         void getEntriesRecursive(IGroupHandle* Group, QList<IEntryHandle*>& EntryList);
216         void rebuildIndices(QList<StdGroup*>& list);
217         void restoreGroupTreeState();
218         //void copyTree(Kdb3Database* db, GroupHandle* orgGroup, IGroupHandle* parent);
219         static bool EntryHandleLessThan(const IEntryHandle* This,const IEntryHandle* Other);
220         static bool EntryHandleLessThanStd(const IEntryHandle* This,const IEntryHandle* Other);
221         static bool StdEntryLessThan(const Kdb3Database::StdEntry& This,const Kdb3Database::StdEntry& Other);
222
223         StdEntry* getEntry(const KpxUuid& uuid);
224         StdEntry* getEntry(EntryHandle* handle);
225         int getEntryListIndex(EntryHandle* handle);
226         EntryHandle* getHandle(StdEntry* entry);
227
228         StdGroup* getGroup(quint32 Id);
229         void deleteGroup(StdGroup* group);
230
231         QList<EntryHandle> EntryHandles;
232         QList<GroupHandle> GroupHandles;
233         QList<StdEntry> Entries;
234         QList<StdGroup> Groups;
235         StdGroup RootGroup;
236         QList<QPixmap>CustomIcons;
237         QFile* File;
238         QString error;
239         bool KeyError;
240         bool PotentialEncodingIssueLatin1;
241         bool PotentialEncodingIssueUTF8;
242         QList<StdEntry> UnknownMetaStreams;
243         QMap<quint32,bool> TreeStateMetaStream;
244         unsigned int KeyTransfRounds;
245         CryptAlgorithm Algorithm;
246         SecData RawMasterKey;
247         SecData RawMasterKey_CP1252;
248         SecData RawMasterKey_Latin1;
249         SecData RawMasterKey_UTF8;
250         SecData MasterKey;
251         quint8 TransfRandomSeed[32];
252         bool hasV4IconMetaStream;
253         bool passwordEncodingChanged;
254 };
255
256 class KeyTransform : public QThread{
257         Q_OBJECT
258         
259         public:
260                 static void transform(quint8* src, quint8* dst, quint8* KeySeed, int rounds);
261         
262         private:
263                 KeyTransform(quint8* pSrc, quint8* pDst, quint8* pKeySeed, int pRounds);
264                 quint8* src;
265                 quint8* dst;
266                 quint8* KeySeed;
267                 int rounds;
268         
269         protected:
270                 void run();
271 };
272
273 class KeyTransformBenchmark : public QThread{
274         Q_OBJECT
275         
276         public:
277                 static int benchmark(int pMSecs);
278         
279         private:
280                 KeyTransformBenchmark(int pMSecs);
281                 int msecs;
282                 int rounds;
283         
284         protected:
285                 void run();
286 };
287
288 #endif