Browse Source

Fixed error handling nil UUIDs in recycle bin.

Also, only create recycle bin on demand (when deleting items).
remove-cryptography-dependency
Herbert Poul 5 years ago
parent
commit
5e89cc5b03
  1. 5
      CHANGELOG.md
  2. 41
      example/pubspec.lock
  3. 23
      lib/src/kdbx_dao.dart
  4. 8
      lib/src/kdbx_object.dart
  5. 2
      pubspec.yaml
  6. 26
      test/kdbx4_test.dart
  7. BIN
      test/keepass2test.kdbx

5
CHANGELOG.md

@ -1,3 +1,8 @@
## 0.3.1
- Fixed error handling nil UUIDs in recycle bin.
Also, only create recycle bin on demand (when deleting items).
## 0.3.0+1 ## 0.3.0+1
- Minor fixes for kdbx 4.x - Minor fixes for kdbx 4.x

41
example/pubspec.lock

@ -8,6 +8,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.2" version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -28,7 +35,7 @@ packages:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.11" version: "1.14.12"
convert: convert:
dependency: transitive dependency: transitive
description: description:
@ -49,7 +56,14 @@ packages:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.1.4"
cryptography:
dependency: transitive
description:
name: cryptography
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
dio: dio:
dependency: transitive dependency: transitive
description: description:
@ -57,6 +71,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.16" version: "2.1.16"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
ffi_helper:
dependency: transitive
description:
name: ffi_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -76,13 +104,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.3" version: "0.3.3"
isolate:
dependency: transitive
description:
name: isolate
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
kdbx: kdbx:
dependency: "direct main" dependency: "direct main"
description: description:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.2.1" version: "0.3.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:

23
lib/src/kdbx_dao.dart

@ -32,27 +32,38 @@ extension KdbxDao on KdbxFile {
return group; return group;
} }
/// Returns the recycle bin, if it exists, null otherwise.
KdbxGroup get recycleBin { KdbxGroup get recycleBin {
final uuid = body.meta.recycleBinUUID.get(); final uuid = body.meta.recycleBinUUID.get();
if (uuid == null) { if (uuid?.isNil != false) {
return _createRecycleBin(); return null;
} }
_logger.finer(() { try {
return findGroupByUuid(uuid);
} catch (e, stackTrace) {
_logger.warning(() {
final groupDebug = body.rootGroup final groupDebug = body.rootGroup
.getAllGroups() .getAllGroups()
.map((g) => '${g.uuid}: ${g.name}') .map((g) => '${g.uuid}: ${g.name}')
.join('\n'); .join('\n');
return 'All Groups: $groupDebug'; return 'All Groups: $groupDebug';
}); });
return findGroupByUuid(uuid); _logger.severe('Inconsistency error, uuid $uuid not found in groups.', e,
stackTrace);
rethrow;
}
}
KdbxGroup getRecycleBinOrCreate() {
return recycleBin ?? _createRecycleBin();
} }
void deleteGroup(KdbxGroup group) { void deleteGroup(KdbxGroup group) {
move(group, recycleBin); move(group, getRecycleBinOrCreate());
} }
void deleteEntry(KdbxEntry entry) { void deleteEntry(KdbxEntry entry) {
move(entry, recycleBin); move(entry, getRecycleBinOrCreate());
} }
void move(KdbxObject kdbxObject, KdbxGroup toGroup) { void move(KdbxObject kdbxObject, KdbxGroup toGroup) {

8
lib/src/kdbx_object.dart

@ -125,6 +125,11 @@ class KdbxUuid {
KdbxUuid.random() KdbxUuid.random()
: this(base64.encode(uuidGenerator.parse(uuidGenerator.v4()))); : this(base64.encode(uuidGenerator.parse(uuidGenerator.v4())));
/// https://tools.ietf.org/html/rfc4122.html#section-4.1.7
/// > The nil UUID is special form of UUID that is specified to have all
/// 128 bits set to zero.
static const NIL = KdbxUuid('AAAAAAAAAAAAAAAAAAAAAA==');
static final Uuid uuidGenerator = static final Uuid uuidGenerator =
Uuid(options: <String, dynamic>{'grng': UuidUtil.cryptoRNG}); Uuid(options: <String, dynamic>{'grng': UuidUtil.cryptoRNG});
@ -142,4 +147,7 @@ class KdbxUuid {
@override @override
int get hashCode => uuid.hashCode; int get hashCode => uuid.hashCode;
/// Whether this is the [NIL] uuid.
bool get isNil => this == NIL;
} }

2
pubspec.yaml

@ -1,6 +1,6 @@
name: kdbx name: kdbx
description: KeepassX format implementation in pure dart. (kdbx 3.x and 4.x support). description: KeepassX format implementation in pure dart. (kdbx 3.x and 4.x support).
version: 0.3.0 version: 0.3.1
homepage: https://github.com/authpass/kdbx.dart homepage: https://github.com/authpass/kdbx.dart
environment: environment:

26
test/kdbx4_test.dart

@ -52,6 +52,17 @@ class Argon2Test extends Argon2Base {
Argon2Hash argon2hash; Argon2Hash argon2hash;
} }
Future<KdbxFile> _readKdbxFile(
String filePath, {
String password = 'asdf',
}) async {
final kdbxFormat = KdbxFormat(Argon2Test());
final data = await File(filePath).readAsBytes();
final file = await kdbxFormat.read(
data, Credentials(ProtectedValue.fromString(password)));
return file;
}
void main() { void main() {
Logger.root.level = Level.ALL; Logger.root.level = Level.ALL;
PrintAppender().attachToLogger(Logger.root); PrintAppender().attachToLogger(Logger.root);
@ -132,6 +143,21 @@ void main() {
File('test_output_chacha20.kdbx').writeAsBytesSync(output); File('test_output_chacha20.kdbx').writeAsBytesSync(output);
}); });
}); });
group('recycle bin test', () {
test('empty recycle bin with "zero" uuid', () async {
final file = await _readKdbxFile('test/keepass2test.kdbx');
final recycleBin = file.recycleBin;
expect(recycleBin, isNull);
});
test('check deleting item', () async {
final file = await _readKdbxFile('test/keepass2test.kdbx');
expect(file.recycleBin, isNull);
final entry = file.body.rootGroup.getAllEntries().first;
file.deleteEntry(entry);
expect(file.recycleBin, isNotNull);
expect(entry.parent, equals(file.recycleBin));
});
});
} }
KdbxEntry _createEntry( KdbxEntry _createEntry(

BIN
test/keepass2test.kdbx

Binary file not shown.
Loading…
Cancel
Save