[or-cvs] r16856: {} Initial glider TODO and format-handling code (in updater/trunk: . lib lib/glider)

nickm at seul.org nickm at seul.org
Thu Sep 11 19:57:46 UTC 2008


Author: nickm
Date: 2008-09-11 15:57:46 -0400 (Thu, 11 Sep 2008)
New Revision: 16856

Added:
   updater/trunk/TODO
   updater/trunk/lib/glider/
   updater/trunk/lib/glider/__init__.py
   updater/trunk/lib/glider/formats.py
Log:
Initial glider TODO and format-handling code

Added: updater/trunk/TODO
===================================================================
--- updater/trunk/TODO	                        (rev 0)
+++ updater/trunk/TODO	2008-09-11 19:57:46 UTC (rev 16856)
@@ -0,0 +1,37 @@
+
+
+o Write spec
+
+. Write server-side code (python)
+  o S-expression lib
+  . Code to manage data formats
+  - Code to wrangle private keys
+    - Generate
+    - Store, load (password-protected)
+    - Print for posterity
+
+  - Code to generate timestamp files
+  - Code to generate mirror files
+  - Code to generate keylist files, and add new keys to them, and
+    remove keys.
+
+- Write client-side code
+  - Decide early if a python implementation will do for v1.
+    IF SO:
+     - Adjust httplib, urllib2 to use socks4a.
+       - Check SOCKS package for suitability as basis for socks4a support?
+     - Look into best packageing practices
+    IF NOT:
+     - Maybe use curllib for downloading, unless there's something
+       better.
+     - Check out Ron's reference code for s-expression handling.
+
+  - Write cacheing code
+  - Write code to pick a mirror
+  - Write code to grab a timestamp file and figure out what to do.
+  - Write code to update other files
+  - Write code to run, telling another process about status,
+    eventually coming up with a list of packages to install or an
+    "A-OK" signal.
+
+  - GUI

Added: updater/trunk/lib/glider/__init__.py
===================================================================
--- updater/trunk/lib/glider/__init__.py	                        (rev 0)
+++ updater/trunk/lib/glider/__init__.py	2008-09-11 19:57:46 UTC (rev 16856)
@@ -0,0 +1,3 @@
+
+__all__ = [ 'formats' ]
+

Added: updater/trunk/lib/glider/formats.py
===================================================================
--- updater/trunk/lib/glider/formats.py	                        (rev 0)
+++ updater/trunk/lib/glider/formats.py	2008-09-11 19:57:46 UTC (rev 16856)
@@ -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)))
+"""



More information about the tor-commits mailing list