[CalendarServer-changes] [1354] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Mar 9 10:46:18 PST 2007


Revision: 1354
          http://trac.macosforge.org/projects/calendarserver/changeset/1354
Author:   cdaboo at apple.com
Date:     2007-03-09 10:46:18 -0800 (Fri, 09 Mar 2007)

Log Message:
-----------
Support digest authentication against open directory. We need a way to not use the qop parameter to do this, so a new
digest factory was created to override that behavior in the base.

Modified Paths:
--------------
    CalendarServer/trunk/conf/caldavd-test.plist
    CalendarServer/trunk/conf/caldavd.plist
    CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/trunk/twistedcaldav/tap.py

Added Paths:
-----------
    CalendarServer/trunk/twistedcaldav/directory/digest.py

Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist	2007-03-09 01:08:13 UTC (rev 1353)
+++ CalendarServer/trunk/conf/caldavd-test.plist	2007-03-09 18:46:18 UTC (rev 1354)
@@ -215,6 +215,8 @@
       <false/>
       <key>Algorithm</key>
       <string>md5</string>
+      <key>Qop</key>
+      <string></string>
     </dict>
 
     <!-- Kerberos/SPNEGO -->

Modified: CalendarServer/trunk/conf/caldavd.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd.plist	2007-03-09 01:08:13 UTC (rev 1353)
+++ CalendarServer/trunk/conf/caldavd.plist	2007-03-09 18:46:18 UTC (rev 1354)
@@ -162,6 +162,8 @@
       <false/>
       <key>Algorithm</key>
       <string>md5</string>
+      <key>Qop</key>
+      <string></string>
     </dict>
 
     <!-- Kerberos/SPNEGO -->

Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-03-09 01:08:13 UTC (rev 1353)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-03-09 18:46:18 UTC (rev 1354)
@@ -35,6 +35,7 @@
 from twisted.internet.threads import deferToThread
 from twisted.internet.reactor import callLater
 from twisted.cred.credentials import UsernamePassword
+from twisted.web2.auth.digest import DigestedCredentials
 
 from twistedcaldav.config import config
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
@@ -502,7 +503,32 @@
                 log.err("Open Directory (node=%s) error while performing basic authentication for user %s: %r"
                         % (self.service.realmName, self.shortName, e))
                 return False
+        elif isinstance(credentials, DigestedCredentials):
+            try:
+                # We need a special format for the "challenge" and "response" strings passed into open directory, as it is
+                # picky about exactly what it receives.
+                
+                challenge = 'Digest realm="%(realm)s", nonce="%(nonce)s", algorithm=%(algorithm)s' % credentials.fields
+                response = ('Digest username="%(username)s", '
+                            'realm="%(realm)s", '
+                            'nonce="%(nonce)s", '
+                            'uri="%(uri)s", '
+                            'response="%(response)s",'
+                            'algorithm=%(algorithm)s') % credentials.fields
 
+                return opendirectory.authenticateUserDigest(
+                    self.service.directory,
+                    self.guid,
+                    self.shortName,
+                    challenge,
+                    response,
+                    credentials.method
+                )
+            except opendirectory.ODError, e:
+                log.err("Open Directory (node=%s) error while performing digest authentication for user %s: %r"
+                        % (self.service.realmName, self.shortName, e))
+                return False
+
         return super(OpenDirectoryRecord, self).verifyCredentials(credentials)
 
 class OpenDirectoryInitError(DirectoryError):

Added: CalendarServer/trunk/twistedcaldav/directory/digest.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/digest.py	                        (rev 0)
+++ CalendarServer/trunk/twistedcaldav/directory/digest.py	2007-03-09 18:46:18 UTC (rev 1354)
@@ -0,0 +1,73 @@
+##
+# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: Cyrus Daboo, cdaboo at apple.com
+##
+
+
+from twisted.web2.auth.digest import DigestCredentialFactory
+
+"""
+Overrides twisted.web2.auth.digest to allow specifying a qop value as a configuration parameter.
+
+"""
+
+class QopDigestCredentialFactory(DigestCredentialFactory):
+    """
+    See twisted.web2.auth.digest.DigestCredentialFactory
+    """
+
+    def __init__(self, algorithm, qop, realm):
+        """
+        @type algorithm: C{str}
+        @param algorithm: case insensitive string that specifies
+            the hash algorithm used, should be either, md5, md5-sess
+            or sha
+
+        @type qop: C{str}
+        @param qop: case insensitive string that specifies
+            the qop to use
+
+        @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
+
+    def getChallenge(self, peer):
+        """
+        Do the default behavior but then strip out any 'qop' from the challenge fields
+        if no qop was specified.
+        """
+
+        challenge = super(QopDigestCredentialFactory, self).getChallenge(peer)
+        if self.qop:
+            challenge['qop'] = self.qop
+        else:
+            del challenge['qop']
+        return challenge
+            
+
+    def decode(self, response, request):
+        """
+        Do the default behavior but then strip out any 'qop' from the credential fields
+        if no qop was specified.
+        """
+
+        credentials = super(QopDigestCredentialFactory, self).decode(response, request)
+        if not self.qop and credentials.fields.has_key('qop'):
+            del credentials.fields['qop']
+        return credentials

Modified: CalendarServer/trunk/twistedcaldav/tap.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/tap.py	2007-03-09 01:08:13 UTC (rev 1353)
+++ CalendarServer/trunk/twistedcaldav/tap.py	2007-03-09 18:46:18 UTC (rev 1354)
@@ -37,7 +37,6 @@
 from twisted.web2.dav import davxml
 from twisted.web2.dav.resource import TwistedACLInheritable
 from twisted.web2.auth.basic import BasicCredentialFactory
-from twisted.web2.auth.digest import DigestCredentialFactory
 from twisted.web2.channel import http
 
 from twisted.web2.log import LogWrapperResource
@@ -48,6 +47,7 @@
 from twistedcaldav.logging import RotatingFileAccessLoggingObserver
 from twistedcaldav.root import RootResource
 from twistedcaldav.resource import CalDAVResource
+from twistedcaldav.directory.digest import QopDigestCredentialFactory
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.directory.aggregate import AggregateDirectoryService
 from twistedcaldav.directory.sudo import SudoDirectoryService
@@ -392,8 +392,9 @@
                     )
 
                 elif scheme == 'digest':
-                    credFactory = DigestCredentialFactory(
+                    credFactory = QopDigestCredentialFactory(
                         schemeConfig['Algorithm'],
+                        schemeConfig['Qop'],
                         realm
                     )
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070309/d2d3be3f/attachment.html


More information about the calendarserver-changes mailing list