On Tue, 21 Feb 2006 16:05:40 +0200, Ilias Lazaridis <[EMAIL PROTECTED]> wrote:
V0.93 with tracd on debian with apache.

when I update the htdigest file (e.g. change of a users password), trac recognizes the new password only after a restart of tracd.

My questions:

a) can I avoid the need of the tracd restart?

I use the attached patch to accomplish this.  The patch also adds support for a 
second kind of hashed password, which you probably don't care about, but 
separating the two features would be a hassle.

Jean-Paul
=== trac/web/standalone.py
==================================================================
--- trac/web/standalone.py	(revision 2046)
+++ trac/web/standalone.py	(revision 2047)
@@ -32,6 +32,7 @@
 import re
 import sys
 import md5
+import sha
 import time
 import socket, errno
 import urllib
@@ -47,39 +48,41 @@
 
 class BasicAuth:
     def __init__(self, htpasswd, realm):
-        self.hash = {}
         self.realm = realm
+        self.htpasswd = htpasswd
         try:
             import crypt
             self.crypt = crypt.crypt
         except ImportError:
             self.crypt = None
-        self.load(htpasswd)
 
     def load(self, filename):
+        self.hash = {}
         fd = open(filename, 'r')
         for line in fd:
             u, h = line.strip().split(':')
-            if '$' in h or self.crypt:
-                self.hash[u] = h
-            else:
-                print >>sys.stderr, 'Warning: cannot parse password for ' \
-                                    'user "%s" without the "crypt" module' % u
+            self.hash[u] = h
 
         if self.hash == {}:
             print >> sys.stderr, "Warning: found no users in file:", filename
 
     def test(self, user, password):
+        self.load(self.htpasswd)
         the_hash = self.hash.get(user)
         if the_hash is None:
             return False
 
+        if sha.new(password).hexdigest() == the_hash:
+            return True
+
         if not '$' in the_hash:
-            return self.crypt(password, the_hash[:2]) == the_hash
+            x = self.crypt(password, the_hash[:2])
+            return x == the_hash
 
         magic, salt = the_hash[1:].split('$')[:2]
         magic = '$' + magic + '$'
-        return md5crypt(password, salt, magic) == the_hash
+        x = md5crypt(password, salt, magic)
+        return x == the_hash
 
     def send_auth_request(self, req):
         req.send_response(401)
@@ -113,15 +116,15 @@
 
     def __init__(self, htdigest, realm):
         self.active_nonces = []
-        self.hash = {}
         self.realm = realm
-        self.load_htdigest(htdigest, realm)
+        self._htdigest = htdigest
 
     def load_htdigest(self, filename, realm):
         """
         Load account information from apache style htdigest files,
         only users from the specified realm are used
         """
+        self.hash = {}
         fd = open(filename, 'r')
         for line in fd.readlines():
             u, r, a1 = line.strip().split(':')
@@ -151,11 +154,12 @@
             self.active_nonces = self.active_nonces[-DigestAuth.MAX_NONCES:]
         req.send_response(401)
         req.send_header('WWW-Authenticate',
-                        'Digest realm="%s", nonce="%s", qop="auth", stale="%s"'
+                        'Digest realm="%s", nonce="%s", qop="auth", stale="%s", hash="sha"'
                         % (self.realm, nonce, stale))
         req.end_headers()
 
     def do_auth(self, req):
+        self.load_htdigest(self._htdigest, self.realm)
         if not 'Authorization' in req.headers or \
                not req.headers['Authorization'].startswith('Digest'):
             self.send_auth_request(req)
_______________________________________________
Trac mailing list
[email protected]
http://lists.edgewall.com/mailman/listinfo/trac

Reply via email to