chiark / gitweb /
httpauth.py: Allow configuration of the hash function.
[chopwood] / httpauth.py
index e29686c97731c46abb5fbe4a5306780e8e4260f9..ea978eb123fa1ffd9b4cee82890d892382a711c5 100644 (file)
@@ -100,7 +100,10 @@ CONF.DEFAULTS.update(
   SECRETLIFE = 30*60,
 
   ## Maximum age of an authentication key, in seconds.
-  SECRETFRESH = 5*60)
+  SECRETFRESH = 5*60,
+
+  ## Hash function to use for crypto.
+  AUTHHASH = H.sha256)
 
 def cleansecrets():
   """Remove dead secrets from the database."""
@@ -152,7 +155,7 @@ def hack_octets(s):
 
 def auth_tag(sec, stamp, nonce, user):
   """Compute a tag using secret SEC on `STAMP.NONCE.USER'."""
-  hmac = HM.HMAC(sec, digestmod = H.sha256)
+  hmac = HM.HMAC(sec, digestmod = CFG.AUTHHASH)
   hmac.update('%d.%s.%s' % (stamp, nonce, user))
   return hack_octets(hmac.digest())
 
@@ -175,6 +178,7 @@ LOGIN_REASONS = {
   'EXPIRED': 'session timed out',
   'BADTAG': 'incorrect tag',
   'NOUSER': 'unknown user name',
+  'LOGOUT': 'explicitly logged out',
   None: None
 }
 
@@ -201,6 +205,9 @@ def check_auth(token, nonce = None):
 
   global NONCE
 
+  ## If the token has been explicitly clobbered, then we're logged out.
+  if token == 'logged-out': raise AuthenticationFailed, 'LOGOUT'
+
   ## Parse the token.
   bits = token.split('.', 3)
   if len(bits) != 4: raise AuthenticationFailed, 'BADTOKEN'
@@ -227,6 +234,16 @@ def check_auth(token, nonce = None):
   ## Done.
   return user
 
+def bake_cookie(value):
+  """
+  Return a properly baked authentication-token cookie with the given VALUE.
+  """
+  return CGI.cookie('chpwd-token', value,
+                    httponly = True,
+                    secure = CGI.SSLP,
+                    path = CFG.SCRIPT_NAME,
+                    max_age = (CFG.SECRETLIFE - CFG.SECRETFRESH))
+
 ###--------------------------------------------------------------------------
 ### Authentication commands.
 
@@ -258,11 +275,6 @@ def cmd_auth(u, pw):
   else:
     t = mint_token(u)
     CGI.redirect(CGI.action('list', u),
-                 set_cookie = CGI.cookie('chpwd-token', t,
-                                         httponly = True,
-                                         secure = CGI.SSLP,
-                                         path = CFG.SCRIPT_NAME,
-                                         max_age = (CFG.SECRETLIFE -
-                                                    CFG.SECRETFRESH)))
+                 set_cookie = bake_cookie(t))
 
 ###----- That's all, folks --------------------------------------------------