diff options
Diffstat (limited to 'tools/readconfig.py')
-rw-r--r-- | tools/readconfig.py | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tools/readconfig.py b/tools/readconfig.py new file mode 100644 index 0000000..5079691 --- /dev/null +++ b/tools/readconfig.py @@ -0,0 +1,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) |