Revision
1464
Author
cdaboo@apple.com
Date
2007-04-10 12:56:07 -0700 (Tue, 10 Apr 2007)

Log Message

Make sure that the digest auth's opaque hash secret is the same for all server processes on one machine, or can
be configured the same for multiple machines.

Modified Paths

Diff

Modified: CalendarServer/trunk/conf/caldavd-test.plist (1463 => 1464)


--- CalendarServer/trunk/conf/caldavd-test.plist	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/conf/caldavd-test.plist	2007-04-10 19:56:07 UTC (rev 1464)
@@ -217,6 +217,8 @@
       <string>md5</string>
       <key>Qop</key>
       <string></string>
+      <key>Secret</key>
+      <string></string>
     </dict>
 
     <!-- Kerberos/SPNEGO -->

Modified: CalendarServer/trunk/conf/caldavd.plist (1463 => 1464)


--- CalendarServer/trunk/conf/caldavd.plist	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/conf/caldavd.plist	2007-04-10 19:56:07 UTC (rev 1464)
@@ -164,6 +164,8 @@
       <string>md5</string>
       <key>Qop</key>
       <string></string>
+      <key>Secret</key>
+      <string></string>
     </dict>
 
     <!-- Kerberos/SPNEGO -->

Modified: CalendarServer/trunk/twistedcaldav/cluster.py (1463 => 1464)


--- CalendarServer/trunk/twistedcaldav/cluster.py	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/twistedcaldav/cluster.py	2007-04-10 19:56:07 UTC (rev 1464)
@@ -92,7 +92,8 @@
              '-o', 'BindHTTPPorts=%s' % (','.join(map(str, self.ports)),),
              '-o', 'BindSSLPorts=%s' % (','.join(map(str, self.sslPorts)),),
              '-o', 'PIDFile=None',
-             '-o', 'ErrorLogFile=None'])
+             '-o', 'ErrorLogFile=None',
+             '-o', 'SharedSecret=%s' % (config.SharedSecret,)])
 
         return args
 

Modified: CalendarServer/trunk/twistedcaldav/config.py (1463 => 1464)


--- CalendarServer/trunk/twistedcaldav/config.py	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/twistedcaldav/config.py	2007-04-10 19:56:07 UTC (rev 1464)
@@ -93,7 +93,8 @@
         "Digest"  : {                       # Digest challenge/response
             "Enabled": True,
             "Algorithm": "md5",
-            "Qop": ""
+            "Qop": "",
+            "Secret": "",
         },
         "Kerberos": {                       # Kerberos/SPNEGO
             "Enabled": False,
@@ -170,6 +171,10 @@
     # A unix socket used for communication between the child and master
     # processes.
     "ControlSocket": "/var/run/caldavd.sock",
+    
+    # A secret key (SHA-1 hash of random string) that is used for internal
+    # crypto operations and shared by multiple server processes
+    "SharedSecret": "",
 }
 
 class Config (object):

Modified: CalendarServer/trunk/twistedcaldav/directory/digest.py (1463 => 1464)


--- CalendarServer/trunk/twistedcaldav/directory/digest.py	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/twistedcaldav/directory/digest.py	2007-04-10 19:56:07 UTC (rev 1464)
@@ -29,7 +29,7 @@
     See twisted.web2.auth.digest.DigestCredentialFactory
     """
 
-    def __init__(self, algorithm, qop, realm):
+    def __init__(self, algorithm, qop, secret, realm):
         """
         @type algorithm: C{str}
         @param algorithm: case insensitive string that specifies
@@ -40,12 +40,18 @@
         @param qop: case insensitive string that specifies
             the qop to use
 
+
+        @type secret: C{str}
+        @param secret: specifies a secret key to be used for opaque value hashing
+
         @type realm: C{str}
         @param realm: case sensitive string that specifies the realm
             portion of the challenge
         """
         super(QopDigestCredentialFactory, self).__init__(algorithm, realm)
         self.qop = qop
+        if secret:
+            self.privateKey = secret
 
     def getChallenge(self, peer):
         """

Modified: CalendarServer/trunk/twistedcaldav/tap.py (1463 => 1464)


--- CalendarServer/trunk/twistedcaldav/tap.py	2007-04-10 18:34:03 UTC (rev 1463)
+++ CalendarServer/trunk/twistedcaldav/tap.py	2007-04-10 19:56:07 UTC (rev 1464)
@@ -16,8 +16,11 @@
 # DRI: David Reid, dreid@apple.com
 ##
 
+from hashlib import sha1
+import random
 import os
 import stat
+import sys
 
 from zope.interface import implements
 
@@ -196,6 +199,11 @@
             log.msg("WARNING: changing umask from: 0%03o to 0%03o" % (
                     oldmask, config.umask,))
         
+        # Generate a shared secret that will be passed to any slave processes
+        if not config.SharedSecret:
+            c = tuple([random.randrange(sys.maxint) for _ in range(3)])
+            config.SharedSecret = sha1('%d%d%d' % c).hexdigest()                   
+
     def checkDirectory(self, dirpath, description, access=None, fail=False, permissions=None, uname=None, gname=None):
         if not os.path.exists(dirpath):
             raise ConfigurationError("%s does not exist: %s" % (description, dirpath,))
@@ -403,9 +411,16 @@
                     )
 
                 elif scheme == 'digest':
+                    secret = schemeConfig['Secret']
+                    if not secret and config.SharedSecret:
+                        log.msg("Using master process shared secret for Digest authentication")
+                        secret = config.SharedSecret
+                    else:
+                        log.msg("No shared secret for Digest authentication")
                     credFactory = QopDigestCredentialFactory(
                         schemeConfig['Algorithm'],
                         schemeConfig['Qop'],
+                        secret,
                         realm
                     )