blob: 6a6eec18b497d0bc755bace79722cb70996c027a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# -*- coding: utf-8 -*-
import io
from contextlib import contextmanager
from .common import read_signature
# from kdb3 import KDB3Reader, KDB3_SIGNATURE
from .kdb4 import KDB4Reader, KDB4_SIGNATURE
BASE_SIGNATURE = 0x9AA2D903
_kdb_readers = {
# KDB3_SIGNATURE[1]: KDB3Reader,
#0xB54BFB66: KDB4Reader, # pre2.x may work, untested
KDB4_SIGNATURE[1]: KDB4Reader,
}
@contextmanager
def open(filename, **credentials):
"""
A contextmanager to open the KeePass file with `filename`. Use a `password`
and/or `keyfile` named argument for decryption.
Files are identified using their signature and a reader suitable for
the file format is intialized and returned.
Note: `keyfile` is currently not supported for v3 KeePass files.
"""
kdb = None
try:
with io.open(filename, 'rb') as stream:
signature = read_signature(stream)
cls = get_kdb_reader(signature)
kdb = cls(stream, **credentials)
yield kdb
kdb.close()
except Exception:
if kdb: kdb.close()
raise
def add_kdb_reader(sub_signature, cls):
"""
Add or overwrite the class used to process a KeePass file.
KeePass uses two signatures to identify files. The base signature is
always `0x9AA2D903`. The second/sub signature varies. For example
KeePassX uses the v3 sub signature `0xB54BFB65` and KeePass2 the v4 sub
signature `0xB54BFB67`.
Use this method to add or replace a class by givin a `sub_signature` as
integer and a class, which should be a subclass of
`keepass.common.KDBFile`.
"""
_kdb_readers[sub_signature] = cls
def get_kdb_reader(signature):
"""
Retrieve the class used to process a KeePass file by `signature`, which
is a a tuple or list with two elements. The first being the base signature
and the second the sub signature as integers.
"""
if signature[0] != BASE_SIGNATURE:
raise IOError('Unknown base signature.')
if signature[1] not in _kdb_readers:
raise IOError('Unknown sub signature.')
return _kdb_readers[signature[1]]
|