+#---------- authentication tokens ----------
+
+_authtoken_digest = hashlib.sha256
+
+def _authtoken_time():
+ return int(time.time())
+
+def _authtoken_hmac(secret, hextime):
+ return hmac.new(secret, hextime, _authtoken_digest).digest()
+
+def authtoken_make(secret):
+ hextime = ('%x' % _authtoken_time()).encode('ascii')
+ mac = _authtoken_hmac(secret, hextime)
+ return hextime + b' ' + base64.b64encode(mac)
+
+def authtoken_check(secret, token, maxskew):
+ (hextime, theirmac64) = token.split(b' ')
+ now = _authtoken_time()
+ then = int(hextime, 16)
+ skew = then - now;
+ if (abs(skew) > maxskew):
+ raise ValueError('too much clock skew (client %ds ahead)' % skew)
+ theirmac = base64.b64decode(theirmac64)
+ ourmac = _authtoken_hmac(secret, hextime)
+ if not hmac.compare_digest(theirmac, ourmac):
+ raise ValueError('invalid token (wrong secret?)')
+ pass
+