summaryrefslogtreecommitdiff
path: root/lib/glider/formats.py
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-09-11 19:57:46 +0000
committerNick Mathewson <nickm@torproject.org>2008-09-11 19:57:46 +0000
commit3b22d6a1fb41ede3b9f5afb84ecd78208fca8559 (patch)
tree1aa8c871f0c3c2aa626f348ccd88cd7c05d8de91 /lib/glider/formats.py
parentc27349f728b2c8e749b7fd6fd13fad9c05c0cc04 (diff)
Initial glider TODO and format-handling code
git-svn-id: file:///home/or/svnrepo/updater/trunk@16856 55e972cd-5a19-0410-ae62-a4d7a52db4cd
Diffstat (limited to 'lib/glider/formats.py')
-rw-r--r--lib/glider/formats.py166
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/glider/formats.py b/lib/glider/formats.py
new file mode 100644
index 0000000..b579848
--- /dev/null
+++ b/lib/glider/formats.py
@@ -0,0 +1,166 @@
+
+import OpenSSL.crypto
+
+import sexp.access
+import sexp.encode
+import time
+import re
+
+class UnknownMethod(Exception):
+ pass
+
+class PublicKey:
+ def format(self):
+ raise NotImplemented()
+ def sign(self, data):
+ # returns a list of method,signature tuples.
+ raise NotImplemented()
+ def checkSignature(self, method, data, signature):
+ # returns True, False, or raises UnknownMethod.
+ raise NotImplemented()
+ def getKeyID(self):
+ raise NotImplemented()
+ def getRoles(self):
+ raise NotImplemented()
+
+class KeyDB:
+ def __init__(self):
+ self.keys = {}
+ def addKey(self, k):
+ self.keys[k.getKeyID()] = k
+ def getKey(self, keyid):
+ return self.keys[keyid]
+
+def rolePathMatches(rolePath, path):
+ """
+
+ >>> rolePath.matches("a/b/c/", "a/b/c/")
+ True
+ >>> rolePath.matches("**/c.*", "a/b/c.txt")
+ True
+ """
+ rolePath = re.escape(rolePath).replace(r'\*\*', r'.*')
+ rolePath = rolePath.replace(r'\*', r'[^/]*')
+ rolePath += "$"
+ return re.match(rolePath, path) != None
+
+def checkSignatures(signed, keyDB, role, path):
+ goodSigs = []
+ badSigs = []
+ unknownSigs = []
+ tangentialSigs = []
+
+ for signature in sexp.access.s_children(signed, "signature"):
+ attrs = signature[1]
+ sig = attrs[2]
+ keyid = s_child(attrs, "keyid")[1]
+ try:
+ key = keyDB.getKey(keyid)
+ except KeyError:
+ unknownSigs.append(keyid)
+ continue
+ method = s_child(attrs, "method")[1]
+ try:
+ result = key.checkSignature(method, data, sig)
+ except UnknownMethod:
+ continue
+ if result == True:
+ if role is not None:
+ for r,p in key.getRoles():
+ if r == role and rolePathMatches(p, path):
+ break
+ else:
+ tangentialSigs.append(sig)
+ continue
+
+ goodSigs.append(keyid)
+ else:
+ badSigs.append(keyid)
+
+def sign(signed, key):
+ assert sexp.access.s_tag(signed) == 'signed'
+ s = signed[1]
+ keyid = key.keyID()
+
+ oldsignatures = [ s for s in signed[2:] if s_child(s[1], "keyid") != keyid ]
+ signed[2:] = oldsignatures
+
+ for method, sig in key.sign(s):
+ signed.append(['signature', [['keyid', keyid], ['method', method]]
+ sig])
+
+def formatTime(t):
+ return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(t))
+
+def parseTime(s):
+ return time.timegm(time.strptime(s, "%Y-%m-%d %H:%M:%S"))
+
+
+TIME_SCHEMA = r"""/\{d}4-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/"""
+
+ATTRS_SCHEMA = r"""(:anyof (_ *))"""
+
+SIGNED_SCHEMA = r"""
+ (=signed
+ _
+ (:someof
+ (=signature ((:unordered
+ (=keyid _) (=method _) .ATTRS)) _)
+ )
+ )"""
+
+KEYFILE_SCHEMA = r"""
+ (=keylist
+ (=ts .TIME)
+ (=keys
+ (:anyof
+ (=key ((:unordered (=roles (:someof (. .))) .ATTRS)) _)
+ ))
+ *
+ )"""
+
+MIRRORLIST_SCHEMA = r"""
+ (=mirrorlist
+ (=ts .TIME)
+ (=mirrors (:anyof
+ (=mirror ((:unordered (=name .) (=urlbase .) (=contents (:someof .))
+ .ATTRS)))))
+ *)
+"""
+
+TIMESTAMP_SCHEMA = r"""
+ (=ts
+ ((:unordered (=at .TIME) (=m .TIME .) (=k .TIME .)
+ (:anyof (=b . . .TIME . .)) .ATTRS))
+ )"""
+
+BUNDLE_SCHEMA = r"""
+ (=bundle
+ (=at .TIME)
+ (=os .)
+ (:maybe (=arch .))
+ (=packages
+ (:someof
+ (. . . . ((:unordered
+ (:maybe (=order . . .))
+ (:maybe (=optional))
+ (:anyof (=gloss . .))
+ (:anyof (=longgloss . .))
+ .ATTRS)))
+ )
+ )
+ *
+ )"""
+
+PACKAGE_SCHEMA = r"""
+ (=package
+ ((:unordred (=name .)
+ (=version .)
+ (=format . (.ATTRS))
+ (=path .)
+ (=ts .TIME)
+ (=digest .)
+ (:anyof (=shortdesc . .))
+ (:anyof (=longdesc . .))
+ .ATTRS)))
+"""