Import Auto-Type associations in KeePass1Reader.

This commit is contained in:
Felix Geyer 2012-07-19 23:21:12 +02:00
parent 8cf6289d9c
commit b6d9c2e486
5 changed files with 95 additions and 1 deletions

View File

@ -567,7 +567,7 @@ Entry* KeePass1Reader::readEntry(QIODevice* cipherStream)
entry->setPassword(QString::fromUtf8(fieldData.constData()));
break;
case 0x0008:
entry->setNotes(QString::fromUtf8(fieldData.constData()));
parseNotes(QString::fromUtf8(fieldData.constData()), entry.data());
break;
case 0x0009:
{
@ -636,6 +636,68 @@ Entry* KeePass1Reader::readEntry(QIODevice* cipherStream)
return entry.take();
}
void KeePass1Reader::parseNotes(const QString& rawNotes, Entry* entry)
{
QRegExp sequenceRegexp("Auto-Type(?:-(\\d+))?: (.+)", Qt::CaseInsensitive, QRegExp::RegExp2);
QRegExp windowRegexp("Auto-Type-Window(?:-(\\d+))?: (.+)", Qt::CaseInsensitive, QRegExp::RegExp2);
QHash<int, QString> sequences;
QMap<int, QStringList> windows;
QStringList notes;
bool lastLineAutoType = false;
Q_FOREACH (QString line, rawNotes.split("\n")) {
line.remove("\r");
if (sequenceRegexp.exactMatch(line)) {
if (sequenceRegexp.cap(1).isEmpty()) {
entry->setDefaultAutoTypeSequence(sequenceRegexp.cap(2));
}
else {
sequences[sequenceRegexp.cap(1).toInt()] = sequenceRegexp.cap(2);
}
lastLineAutoType = true;
}
else if (windowRegexp.exactMatch(line)) {
int nr;
if (windowRegexp.cap(1).isEmpty()) {
nr = -1; // special number that matches no other sequence
}
else {
nr = windowRegexp.cap(1).toInt();
}
windows[nr].append(windowRegexp.cap(2));
lastLineAutoType = true;
}
else {
// don't add empty lines following a removed auto-type line
if (!lastLineAutoType || !line.isEmpty()) {
notes.append(line);
}
lastLineAutoType = false;
}
}
entry->setNotes(notes.join("\n"));
QMapIterator<int, QStringList> i(windows);
while (i.hasNext()) {
i.next();
QString sequence = sequences.value(i.key());
Q_FOREACH (const QString& window, i.value()) {
AutoTypeAssociations::Association assoc;
assoc.window = window;
assoc.sequence = sequence;
entry->autoTypeAssociations()->add(assoc);
}
}
}
bool KeePass1Reader::constructGroupTree(const QList<Group*> groups)
{
for (int i = 0; i < groups.size(); i++) {

View File

@ -57,6 +57,7 @@ private:
bool verifyKey(SymmetricCipherStream* cipherStream);
Group* readGroup(QIODevice* cipherStream);
Entry* readEntry(QIODevice* cipherStream);
void parseNotes(const QString& rawNotes, Entry* entry);
bool constructGroupTree(const QList<Group*> groups);
void parseMetaStream(const Entry* entry);
bool parseGroupTreeState(const QByteArray& data);

View File

@ -139,6 +139,36 @@ void TestKeePass1Reader::testGroupExpanded()
false);
}
void TestKeePass1Reader::testAutoType()
{
Group* group = m_db->rootGroup()->children().at(0)->children().at(0);
QCOMPARE(group->entries().size(), 2);
Entry* entry1 = group->entries().at(0);
QCOMPARE(entry1->notes(), QString("last line"));
QCOMPARE(entry1->defaultAutoTypeSequence(), QString("{USERNAME}{ENTER}"));
QCOMPARE(entry1->autoTypeAssociations()->size(), 5);
QCOMPARE(entry1->autoTypeAssociations()->get(0).sequence, QString(""));
QCOMPARE(entry1->autoTypeAssociations()->get(0).window, QString("a window"));
QCOMPARE(entry1->autoTypeAssociations()->get(1).sequence, QString(""));
QCOMPARE(entry1->autoTypeAssociations()->get(1).window, QString("a second window"));
QCOMPARE(entry1->autoTypeAssociations()->get(2).sequence, QString("{PASSWORD}{ENTER}"));
QCOMPARE(entry1->autoTypeAssociations()->get(2).window, QString("Window Nr 1a"));
QCOMPARE(entry1->autoTypeAssociations()->get(3).sequence, QString("{PASSWORD}{ENTER}"));
QCOMPARE(entry1->autoTypeAssociations()->get(3).window, QString("Window Nr 1b"));
QCOMPARE(entry1->autoTypeAssociations()->get(4).sequence, QString(""));
QCOMPARE(entry1->autoTypeAssociations()->get(4).window, QString("Window 2"));
Entry* entry2 = group->entries().at(1);
QCOMPARE(entry2->notes(), QString("start line\nend line"));
QCOMPARE(entry2->defaultAutoTypeSequence(), QString(""));
QCOMPARE(entry2->autoTypeAssociations()->size(), 2);
QCOMPARE(entry2->autoTypeAssociations()->get(0).sequence, QString(""));
QCOMPARE(entry2->autoTypeAssociations()->get(0).window, QString("Main Window"));
QCOMPARE(entry2->autoTypeAssociations()->get(1).sequence, QString(""));
QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("Test Window"));
}
void TestKeePass1Reader::testFileKey()
{
QFETCH(QString, type);

View File

@ -33,6 +33,7 @@ private Q_SLOTS:
void testMasterKey();
void testCustomIcons();
void testGroupExpanded();
void testAutoType();
void testFileKey();
void testFileKey_data();
void testCompositeKey();

Binary file not shown.