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
|
import io
import ecdsa
import hashlib
import yaml
import base64
import sys
class ErrorHandlingDict(dict):
def __init__(self, filename, path):
self._filename = filename
self._path = path
dict.__init__({})
def __missing__(self, key):
if self._path:
path = ", ".join(self._path)
else:
path = "the top level"
print >>sys.stderr, "error: could not find configuration key '%s' at %s in %s" % (key, path, self._filename)
sys.exit(1)
def errorhandlify(term, filename, path=[]):
if isinstance(term, basestring):
return term
elif isinstance(term, int):
return term
elif isinstance(term, dict):
result = ErrorHandlingDict(filename, path)
for k, v in term.items():
result[k] = errorhandlify(v, filename, path + [k])
return result
elif isinstance(term, list):
return [errorhandlify(e, filename, path + ["item %d" % i]) for i, e in enumerate(term, start=1)]
else:
print "unknown type", type(term)
sys.exit(1)
def verify_and_read_config(filename, publickey_base64):
rawconfig = open(filename).read()
signature = open(filename + ".sig").read()
publickey = base64.decodestring(publickey_base64)
try:
vk = ecdsa.VerifyingKey.from_der(publickey)
vk.verify(signature, rawconfig, hashfunc=hashlib.sha256,
sigdecode=ecdsa.util.sigdecode_der)
except ecdsa.keys.BadSignatureError:
print >>sys.stderr, "error: configuration file %s did not have a correct signature" % (filename,)
sys.exit(1)
return errorhandlify(yaml.load(io.BytesIO(rawconfig), yaml.SafeLoader), filename)
def read_config(filename):
return errorhandlify(yaml.load(open(filename), yaml.SafeLoader), filename)
|