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 _______________________________________________ Server-devel mailing list Server-devel@lists.laptop.org http://lists.laptop.org/listinfo/server-devel