[Server-devel] [PATCH] xs-activation: Support creating rtcreset signatures with master key
Daniel Drake
dsd at laptop.org
Fri Dec 30 16:48:59 EST 2011
If the master keypair is available as lease.public/lease.private,
use it to create rtc reset signatures (rather than relying on
delegations).
The UUID of the client must be known to the server, stored in
the moodle database.
---
oat.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
xs-activation-signer.py | 48 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 1 deletions(-)
For the moment this patch is just for review as "sample code" - it relies
on the addition of UUIDs into the moodle database, which will happen at
a later date.
diff --git a/oat.py b/oat.py
index bb22a23..7ad78c9 100644
--- a/oat.py
+++ b/oat.py
@@ -63,6 +63,23 @@ class oat:
return False
+ def get_uuid(self, sn):
+ if not self.mdb_available():
+ return False
+
+ mdbh = self.get_mdb_handle()
+ mdbc = mdbh.cursor()
+ sql = """SELECT uuid
+ FROM mdl_oat_laptops
+ WHERE serialnum=%s
+ """
+ mdbc.execute(sql, [sn])
+ if mdbc.rowcount == 1:
+ rows = mdbc.fetchall()
+ return rows[0][0]
+
+ return False
+
def mark_served_stolen(self, sn):
"""Returns False or the string 'STOLEN'"""
@@ -256,11 +273,19 @@ class oat:
return response
def get_rtcreset(self, sn, currentrtc, nonce):
+ newrtc = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
+
+ # use the master key to generate the rtcreset, if it is available
+ kpath = self.get_master_lease_key_path()
+ if kpath:
+ uuid = self.get_uuid(sn)
+ if uuid:
+ return self.generate_rtcreset(sn, uuid, currentrtc, nonce, newrtc)
+
# attempt to build a sig02 delegated rtcreset
kpath = self.get_key_path()
ldpath = self.get_lease_delegation_path(sn)
if kpath and ldpath:
- newrtc = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
return self.generate_delegated_rtcreset(sn, currentrtc, nonce, newrtc)
def mdb_available(self):
@@ -286,6 +311,14 @@ class oat:
else:
return False
+ def get_master_lease_key_path(self):
+ path = os.path.join(self.BASEDIR, 'keys', 'lease.private')
+ if os.path.exists(path):
+ # strip ".private" suffix
+ return path[:-8]
+ else:
+ return False
+
def get_lease_delegation_path(self, sn):
path = os.path.join(self.BASEDIR, 'lease-delegations',
sn[-2:], sn)
@@ -324,6 +357,22 @@ class oat:
return lease;
+ def generate_rtcreset(self, sn, uuid, currentrtc, nonce, newrtc):
+ (fh, tmpfpath) = tempfile.mkstemp(dir='/var/lib/xs-activation/tmp')
+ os.write(fh, uuid)
+ os.close(fh)
+
+ fname = "rtc01_%s_%s_%s_%s_%s" % (sn, currentrtc, nonce, newrtc, hexlify(os.urandom(8)))
+ reqpath = '/var/lib/xs-activation/req/' + fname
+ os.rename(tmpfpath, reqpath)
+
+ rtcreset = self.get_signed_output(fname)
+ if rtcreset == None:
+ self.log_error("Timed out waiting for signed response")
+ raise RuntimeError("Timed out waiting for signed response")
+
+ return rtcreset
+
def generate_delegated_rtcreset(self, sn, currentrtc, nonce, newrtc):
fname = "rtc01delegated_%s_%s_%s_%s_%s" % (sn, currentrtc, nonce, newrtc, hexlify(os.urandom(8)))
reqpath = '/var/lib/xs-activation/req/' + fname
diff --git a/xs-activation-signer.py b/xs-activation-signer.py
index 46ccec2..5383b1a 100755
--- a/xs-activation-signer.py
+++ b/xs-activation-signer.py
@@ -225,6 +225,52 @@ def generate_multiple_delegated_leases(dirpath, fname, fpath, params):
destpath = '/var/lib/xs-activation/done/' + fname
save_atomically(destpath, cjson.write([1,leases]))
+def serve_rtcreset(dirpath, fname, fpath, params):
+ # read UUID
+ fd = open(fpath, 'r')
+ uuid = fd.read()
+ fd.close()
+ os.unlink(fpath)
+
+ if not uuid:
+ raise RuntimeError('Missing UUID')
+
+ randid = params.pop()
+ newrtc = params.pop()
+ nonce = params.pop()
+ currentrtc = params.pop()
+
+ sn = params.pop()
+ if not validate_sn(sn):
+ raise RuntimeError('Invalid SN')
+
+ if len(currentrtc) != 16 or currentrtc[15] != 'Z' or currentrtc[8] != 'T':
+ log_error("Unrecognised rtcreset timestamp")
+ exit(1)
+
+ if not nonce.isdigit():
+ log_error("Unrecognised rtcreset nonce")
+ exit(1)
+
+ # find uuid and signing key
+ myoat = oat.oat()
+
+ kpath = myoat.get_master_lease_key_path()
+ if not kpath:
+ log_error("No master signing key available")
+ exit(1)
+
+ # prep params
+ cmd = ['/usr/bin/obc-make-rtcreset',
+ '--signingkey', kpath,
+ sn, uuid, currentrtc, nonce, newrtc]
+ log_error(cmd)
+ rtcreset = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE).communicate()[0]
+
+ destpath = '/var/lib/xs-activation/done/' + fname
+ save_atomically(destpath, rtcreset)
+
def serve_delegated_rtcreset(dirpath, fname, fpath, params):
# remove empty/unused file
os.unlink(fpath)
@@ -323,6 +369,8 @@ try:
serve_delegated_lease(dirpath, fname, fpath, params)
elif cmd == 'multiact01':
generate_multiple_delegated_leases(dirpath, fname, fpath, params)
+ elif cmd == 'rtc01':
+ serve_rtcreset(dirpath, fname, fpath, params)
elif cmd == 'rtc01delegated':
serve_delegated_rtcreset(dirpath, fname, fpath, params)
else:
--
1.7.7.4
More information about the Server-devel
mailing list