[CalendarServer-changes] [3539] PyOpenDirectory/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Dec 17 10:15:00 PST 2008


Revision: 3539
          http://trac.macosforge.org/projects/calendarserver/changeset/3539
Author:   cdaboo at apple.com
Date:     2008-12-17 10:14:59 -0800 (Wed, 17 Dec 2008)
Log Message:
-----------
Cache nodes on which we do authentication so we don't keeping opening/closing for every auth.

Modified Paths:
--------------
    PyOpenDirectory/trunk/setup.py
    PyOpenDirectory/trunk/src/CDirectoryService.cpp
    PyOpenDirectory/trunk/src/CDirectoryService.h
    PyOpenDirectory/trunk/src/CDirectoryServiceManager.cpp
    PyOpenDirectory/trunk/src/CDirectoryServiceManager.h
    PyOpenDirectory/trunk/src/PythonWrapper.cpp
    PyOpenDirectory/trunk/test_auth.py

Added Paths:
-----------
    PyOpenDirectory/trunk/src/CDirectoryServiceAuth.cpp
    PyOpenDirectory/trunk/src/CDirectoryServiceAuth.h

Modified: PyOpenDirectory/trunk/setup.py
===================================================================
--- PyOpenDirectory/trunk/setup.py	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/setup.py	2008-12-17 18:14:59 UTC (rev 3539)
@@ -31,6 +31,7 @@
             'src/PythonWrapper.cpp',
             'src/CDirectoryServiceManager.cpp',
             'src/CDirectoryService.cpp',
+            'src/CDirectoryServiceAuth.cpp',
             'src/CDirectoryServiceException.cpp',
             'src/CFStringUtil.cpp',
             'src/base64.cpp',

Modified: PyOpenDirectory/trunk/src/CDirectoryService.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.cpp	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/src/CDirectoryService.cpp	2008-12-17 18:14:59 UTC (rev 3539)
@@ -95,13 +95,15 @@
     }
     catch(CDirectoryServiceException& dserror)
     {
-        dserror.SetPythonException();
+		if (using_python)
+			dserror.SetPythonException();
         return NULL;
     }
     catch(...)
     {
         CDirectoryServiceException dserror;
-        dserror.SetPythonException();
+		if (using_python)
+	        dserror.SetPythonException();
         return NULL;
     }
 }
@@ -134,13 +136,15 @@
     }
     catch(CDirectoryServiceException& dserror)
     {
-        dserror.SetPythonException();
+		if (using_python)
+	        dserror.SetPythonException();
         return NULL;
     }
     catch(...)
     {
         CDirectoryServiceException dserror;
-        dserror.SetPythonException();
+		if (using_python)
+	        dserror.SetPythonException();
         return NULL;
     }
 }
@@ -171,79 +175,19 @@
     }
     catch(CDirectoryServiceException& dserror)
     {
-        dserror.SetPythonException();
+		if (using_python)
+	        dserror.SetPythonException();
         return NULL;
     }
     catch(...)
     {
         CDirectoryServiceException dserror;
-        dserror.SetPythonException();
+		if (using_python)
+	        dserror.SetPythonException();
         return NULL;
     }
 }
 
-// AuthenticateUserBasic
-//
-// Authenticate a user to the directory using plain text credentials.
-//
-// @param nodename: the directory nodename for the user record.
-// @param user: the uid of the user.
-// @param pswd: the plain text password to authenticate with.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result, bool using_python)
-{
-    try
-    {
-        StPythonThreadState threading(using_python);
-
-        result = NativeAuthenticationBasicToNode(nodename, user, pswd);
-        return true;
-    }
-    catch(CDirectoryServiceException& dserror)
-    {
-        dserror.SetPythonException();
-        return false;
-    }
-    catch(...)
-    {
-        CDirectoryServiceException dserror;
-        dserror.SetPythonException();
-        return false;
-    }
-}
-
-// AuthenticateUserDigest
-//
-// Authenticate a user to the directory using HTTP DIGEST credentials.
-//
-// @param nodename: the directory nodename for the user record.
-// @param challenge: HTTP challenge sent by server.
-// @param response: HTTP response sent by client.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result, bool using_python)
-{
-    try
-    {
-        StPythonThreadState threading(using_python);
-
-        result = NativeAuthenticationDigestToNode(nodename, user, challenge, response, method);
-        return true;
-    }
-    catch(CDirectoryServiceException& dserror)
-    {
-        dserror.SetPythonException();
-        return false;
-    }
-    catch(...)
-    {
-        CDirectoryServiceException dserror;
-        dserror.SetPythonException();
-        return false;
-    }
-}
-
 #pragma mark -----Private API
 
 // _ListAllRecordsWithAttributes
@@ -761,216 +705,6 @@
     return result;
 }
 
-// NativeAuthenticationBasicToNode
-//
-// Authenticate a user to the directory.
-//
-// @param nodename: the node to authenticate to.
-// @param user: the uid of the user.
-// @param pswd: the plain text password to authenticate with.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::NativeAuthenticationBasicToNode(const char* nodename, const char* user, const char* pswd)
-{
-    bool result = false;
-    tDirNodeReference node = 0L;
-    tDataNodePtr authType = NULL;
-    tDataBufferPtr authData = NULL;
-    tContextData context = NULL;
-
-    try
-    {
-        // Make sure we have a valid directory service
-        OpenService();
-
-        // Open the node we want to query
-        node = OpenNamedNode(nodename);
-
-        CreateBuffer();
-
-        // First, specify the type of authentication.
-        authType = ::dsDataNodeAllocateString(mDir, kDSStdAuthClearText);
-
-        // Build input data
-        //  Native authentication is a one step authentication scheme.
-        //  Step 1
-        //      Send: <length><recordname>
-        //            <length><cleartextpassword>
-        //   Receive: success or failure.
-        UInt32 aDataBufSize = sizeof(UInt32) + ::strlen(user) + sizeof(UInt32) + ::strlen(pswd);
-        authData = ::dsDataBufferAllocate(mDir, aDataBufSize);
-        if (authData == NULL)
-            ThrowIfDSErr(eDSNullDataBuff);
-        UInt32 aCurLength = 0;
-        UInt32 aTempLength = ::strlen(user);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), user,  aTempLength);
-        aCurLength += aTempLength;
-
-        aTempLength = ::strlen(pswd);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), pswd,  aTempLength);
-
-        authData->fBufferLength = aDataBufSize;
-
-        // Do authentication
-        tDirStatus dirStatus = ::dsDoDirNodeAuth(node, authType, true,  authData,  mData, &context);
-        result = (dirStatus == eDSNoErr);
-
-        // Cleanup
-        ::dsDataBufferDeAllocate(mDir, authData);
-        authData = NULL;
-        ::dsDataNodeDeAllocate(mDir, authType);
-        authType = NULL;
-        RemoveBuffer();
-        if (node != 0L)
-        {
-            ::dsCloseDirNode(node);
-            node = 0L;
-        }
-        CloseService();
-    }
-    catch(...)
-    {
-        // Cleanup
-        if (authData != NULL)
-            ::dsDataBufferDeAllocate(mDir, authData);
-        if (authType != NULL)
-            ::dsDataNodeDeAllocate(mDir, authType);
-        RemoveBuffer();
-        if (node != 0L)
-        {
-            ::dsCloseDirNode(node);
-            node = 0L;
-        }
-        CloseService();
-
-        throw;
-    }
-
-    return result;
-}
-
-// NativeAuthenticationDigestToNode
-//
-// Authenticate a user to the directory.
-//
-// @param nodename: the node to authenticate to.
-// @param user: the uid of the user.
-// @param challenge: the server challenge.
-// @param response: the client response.
-// @param method: the HTTP method.
-// @return: true if authentication succeeds, false otherwise.
-//
-bool CDirectoryService::NativeAuthenticationDigestToNode(const char* nodename, const char* user,
-                                                         const char* challenge, const char* response, const char* method)
-{
-    bool result = false;
-    tDirNodeReference node = 0L;
-    tDataNodePtr authType = NULL;
-    tDataBufferPtr authData = NULL;
-    tContextData context = NULL;
-
-    try
-    {
-        // Make sure we have a valid directory service
-        OpenService();
-
-        // Open the node we want to query
-        node = OpenNamedNode(nodename);
-
-        CreateBuffer();
-
-        // First, specify the type of authentication.
-        authType = ::dsDataNodeAllocateString(mDir, kDSStdAuthDIGEST_MD5);
-
-        // Build input data
-        //  Native authentication is a one step authentication scheme.
-        //  Step 1
-        //      Send: <length><user>
-        //              <length><challenge>
-        //            <length><response>
-        //              <length><method>
-        //   Receive: success or failure.
-        UInt32 aDataBufSize = sizeof(UInt32) + ::strlen(user) +
-                              sizeof(UInt32) + ::strlen(challenge) +
-                              sizeof(UInt32) + ::strlen(response) +
-                              sizeof(UInt32) + ::strlen(method);
-        authData = ::dsDataBufferAllocate(mDir, aDataBufSize);
-        if (authData == NULL)
-            ThrowIfDSErr(eDSNullDataBuff);
-        UInt32 aCurLength = 0;
-        UInt32 aTempLength = ::strlen(user);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), user,  aTempLength);
-        aCurLength += aTempLength;
-
-        aTempLength = ::strlen(challenge);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), challenge,  aTempLength);
-        aCurLength += aTempLength;
-
-        aTempLength = ::strlen(response);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), response,  aTempLength);
-        aCurLength += aTempLength;
-
-        aTempLength = ::strlen(method);
-        ::memcpy(&(authData->fBufferData[aCurLength]), &aTempLength,  sizeof(UInt32));
-        aCurLength += sizeof(UInt32);
-
-        ::memcpy(&(authData->fBufferData[aCurLength]), method,  aTempLength);
-
-        authData->fBufferLength = aDataBufSize;
-
-        // Do authentication
-        tDirStatus dirStatus = ::dsDoDirNodeAuth(node, authType, true,  authData,  mData, &context);
-        result = (dirStatus == eDSNoErr);
-
-        // Cleanup
-        ::dsDataBufferDeAllocate(mDir, authData);
-        authData = NULL;
-        ::dsDataNodeDeAllocate(mDir, authType);
-        authType = NULL;
-        RemoveBuffer();
-        if (node != 0L)
-        {
-            ::dsCloseDirNode(node);
-            node = 0L;
-        }
-        CloseService();
-    }
-    catch(...)
-    {
-        // Cleanup
-        if (authData != NULL)
-            ::dsDataBufferDeAllocate(mDir, authData);
-        if (authType != NULL)
-            ::dsDataNodeDeAllocate(mDir, authType);
-        RemoveBuffer();
-        if (node != 0L)
-        {
-            ::dsCloseDirNode(node);
-            node = 0L;
-        }
-        CloseService();
-
-        throw;
-    }
-
-    return result;
-}
-
 // OpenService
 //
 // Open the directory service.
@@ -1014,9 +748,9 @@
     mNode = OpenNamedNode(mNodeName);
 }
 
-// OpenNode
+// OpenNamedNode
 //
-// Open a node in the directory.
+// Open a named node in the directory.
 //
 // @param nodename: the name of the node to open.
 // @return: node reference if success, NULL otherwise.

Modified: PyOpenDirectory/trunk/src/CDirectoryService.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryService.h	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/src/CDirectoryService.h	2008-12-17 18:14:59 UTC (rev 3539)
@@ -29,17 +29,14 @@
 {
 public:
     CDirectoryService(const char* nodename);
-    ~CDirectoryService();
+    virtual ~CDirectoryService();
 
     CFMutableArrayRef ListAllRecordsWithAttributes(CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
     CFMutableArrayRef QueryRecordsWithAttribute(const char* attr, const char* value, int matchType, bool casei, CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
     CFMutableArrayRef QueryRecordsWithAttributes(const char* query, bool casei, CFArrayRef recordTypes, CFDictionaryRef attributes, UInt32 maxRecordCount=0, bool using_python=true);
 
-    bool AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result, bool using_python=true);
-    bool AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result, bool using_python=true);
+protected:
 
-private:
-
     class StPythonThreadState
     {
     public:
@@ -70,14 +67,11 @@
     CFMutableArrayRef _ListAllRecordsWithAttributes(CFArrayRef recordTypes, CFArrayRef names, CFDictionaryRef attrs, UInt32 maxRecordCount);
     CFMutableArrayRef _QueryRecordsWithAttributes(const char* attr, const char* value, int matchType, const char* compound, bool casei, CFArrayRef recordTypes, CFDictionaryRef attrs, UInt32 maxRecordCount);
 
-    bool NativeAuthenticationBasicToNode(const char* nodename, const char* user, const char* pswd);
-    bool NativeAuthenticationDigestToNode(const char* nodename, const char* user, const char* challenge, const char* response, const char* method);
+    virtual void OpenService();
+    virtual void CloseService();
 
-    void OpenService();
-    void CloseService();
-
     void OpenNode();
-    tDirNodeReference OpenNamedNode(const char* nodename);
+    virtual tDirNodeReference OpenNamedNode(const char* nodename);
     void CloseNode();
 
     void CreateBuffer();

Added: PyOpenDirectory/trunk/src/CDirectoryServiceAuth.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryServiceAuth.cpp	                        (rev 0)
+++ PyOpenDirectory/trunk/src/CDirectoryServiceAuth.cpp	2008-12-17 18:14:59 UTC (rev 3539)
@@ -0,0 +1,303 @@
+/**
+ * A class that wraps high-level Directory Service calls needed by the
+ * CalDAV server.
+ **
+ * Copyright (c) 2006-2008 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.
+ **/
+
+#include "CDirectoryServiceAuth.h"
+
+#include "CDirectoryServiceException.h"
+
+#pragma mark -----Public API
+
+CDirectoryServiceAuth::CDirectoryServiceAuth() :
+	CDirectoryService("")
+{
+}
+
+CDirectoryServiceAuth::~CDirectoryServiceAuth()
+{
+	// Clean-up
+	CloseService();
+}
+
+// AuthenticateUserBasic
+//
+// Authenticate a user to the directory using plain text credentials.
+//
+// @param nodename: the directory nodename for the user record.
+// @param user: the uid of the user.
+// @param pswd: the plain text password to authenticate with.
+// @return: true if authentication succeeds, false otherwise.
+//
+bool CDirectoryServiceAuth::AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result, bool using_python)
+{
+    try
+    {
+        StPythonThreadState threading(using_python);
+
+        result = NativeAuthenticationBasicToNode(nodename, user, pswd);
+        return true;
+    }
+    catch(CDirectoryServiceException& dserror)
+    {
+		if (using_python)
+	        dserror.SetPythonException();
+        return false;
+    }
+    catch(...)
+    {
+        CDirectoryServiceException dserror;
+		if (using_python)
+	        dserror.SetPythonException();
+        return false;
+    }
+}
+
+// AuthenticateUserDigest
+//
+// Authenticate a user to the directory using HTTP DIGEST credentials.
+//
+// @param nodename: the directory nodename for the user record.
+// @param challenge: HTTP challenge sent by server.
+// @param response: HTTP response sent by client.
+// @return: true if authentication succeeds, false otherwise.
+//
+bool CDirectoryServiceAuth::AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result, bool using_python)
+{
+    try
+    {
+        StPythonThreadState threading(using_python);
+
+        result = NativeAuthenticationDigestToNode(nodename, user, challenge, response, method);
+        return true;
+    }
+    catch(CDirectoryServiceException& dserror)
+    {
+		if (using_python)
+	        dserror.SetPythonException();
+        return false;
+    }
+    catch(...)
+    {
+        CDirectoryServiceException dserror;
+		if (using_python)
+	        dserror.SetPythonException();
+        return false;
+    }
+}
+
+#pragma mark -----Private API
+
+// NativeAuthenticationBasicToNode
+//
+// Authenticate a user to the directory.
+//
+// @param nodename: the node to authenticate to.
+// @param user: the uid of the user.
+// @param pswd: the plain text password to authenticate with.
+// @return: true if authentication succeeds, false otherwise.
+//
+bool CDirectoryServiceAuth::NativeAuthenticationBasicToNode(const char* nodename, const char* user, const char* pswd)
+{
+    bool result = false;
+    tDirNodeReference node = 0L;
+    tDataNodePtr authType = NULL;
+    tDataBufferPtr authData = NULL;
+    tContextData context = NULL;
+
+    try
+    {
+        // Make sure we have a valid directory service
+        OpenService();
+
+        // Open the node we want to query
+        node = OpenNamedNode(nodename);
+
+        CreateBuffer();
+
+        // First, specify the type of authentication.
+        authType = ::dsDataNodeAllocateString(mDir, kDSStdAuthClearText);
+
+        // Build input data
+        //  Native authentication is a one step authentication scheme.
+        //  Step 1
+        //      Send: <length><recordname>
+        //            <length><cleartextpassword>
+        //   Receive: success or failure.
+        UInt32 aDataBufSize = sizeof(UInt32) + ::strlen(user) + sizeof(UInt32) + ::strlen(pswd);
+        authData = ::dsDataBufferAllocate(mDir, aDataBufSize);
+        if (authData == NULL)
+            ThrowIfDSErr(eDSNullDataBuff);
+
+		// Fill the buffer
+		::dsFillAuthBuffer(authData, 2,
+						   ::strlen(user), user,
+						   ::strlen(pswd), pswd);
+
+        // Do authentication
+        tDirStatus dirStatus = ::dsDoDirNodeAuth(node, authType, true,  authData,  mData, &context);
+        result = (dirStatus == eDSNoErr);
+
+        // Cleanup
+        ::dsDataBufferDeAllocate(mDir, authData);
+        authData = NULL;
+        ::dsDataNodeDeAllocate(mDir, authType);
+        authType = NULL;
+        RemoveBuffer();
+    }
+    catch(...)
+    {
+        // Cleanup
+        if (authData != NULL)
+            ::dsDataBufferDeAllocate(mDir, authData);
+        if (authType != NULL)
+            ::dsDataNodeDeAllocate(mDir, authType);
+        RemoveBuffer();
+        CloseService();
+
+        throw;
+    }
+
+    return result;
+}
+
+// NativeAuthenticationDigestToNode
+//
+// Authenticate a user to the directory.
+//
+// @param nodename: the node to authenticate to.
+// @param user: the uid of the user.
+// @param challenge: the server challenge.
+// @param response: the client response.
+// @param method: the HTTP method.
+// @return: true if authentication succeeds, false otherwise.
+//
+bool CDirectoryServiceAuth::NativeAuthenticationDigestToNode(const char* nodename, const char* user,
+                                                         const char* challenge, const char* response, const char* method)
+{
+    bool result = false;
+    tDirNodeReference node = 0L;
+    tDataNodePtr authType = NULL;
+    tDataBufferPtr authData = NULL;
+    tContextData context = NULL;
+
+    try
+    {
+        // Make sure we have a valid directory service
+        OpenService();
+
+        // Open the node we want to query
+        node = OpenNamedNode(nodename);
+
+        CreateBuffer();
+
+        // First, specify the type of authentication.
+        authType = ::dsDataNodeAllocateString(mDir, kDSStdAuthDIGEST_MD5);
+
+        // Build input data
+        //  Native authentication is a one step authentication scheme.
+        //  Step 1
+        //      Send: <length><user>
+        //            <length><challenge>
+        //            <length><response>
+        //            <length><method>
+        //   Receive: success or failure.
+        UInt32 aDataBufSize = sizeof(UInt32) + ::strlen(user) +
+                              sizeof(UInt32) + ::strlen(challenge) +
+                              sizeof(UInt32) + ::strlen(response) +
+                              sizeof(UInt32) + ::strlen(method);
+        authData = ::dsDataBufferAllocate(mDir, aDataBufSize);
+        if (authData == NULL)
+            ThrowIfDSErr(eDSNullDataBuff);
+		
+		// Fill the buffer
+		::dsFillAuthBuffer(authData, 4,
+						   ::strlen(user), user,
+						   ::strlen(challenge), challenge,
+						   ::strlen(response), response,
+						   ::strlen(method), method);
+
+        // Do authentication
+        tDirStatus dirStatus = ::dsDoDirNodeAuth(node, authType, true,  authData,  mData, &context);
+        result = (dirStatus == eDSNoErr);
+
+        // Cleanup
+        ::dsDataBufferDeAllocate(mDir, authData);
+        authData = NULL;
+        ::dsDataNodeDeAllocate(mDir, authType);
+        authType = NULL;
+        RemoveBuffer();
+    }
+    catch(...)
+    {
+        // Cleanup
+        if (authData != NULL)
+            ::dsDataBufferDeAllocate(mDir, authData);
+        if (authType != NULL)
+            ::dsDataNodeDeAllocate(mDir, authType);
+        RemoveBuffer();
+        CloseService();
+
+        throw;
+    }
+
+    return result;
+}
+
+// CloseService
+//
+// Close the directory service if previously open.
+// Also close any open/cached nodes.
+//
+void CDirectoryServiceAuth::CloseService()
+{
+    if (mDir != 0L)
+    {
+		// Close all open nodes
+		for(TNodeMap::const_iterator iter = mNodeMap.begin(); iter != mNodeMap.end(); iter++)
+		{
+            ::dsCloseDirNode((*iter).second);
+		}
+		mNodeMap.clear();
+    }
+	
+	CDirectoryService::CloseService();
+}
+
+// OpenNamedNode
+//
+// Open a named node in the directory.
+//
+// @param nodename: the name of the node to open.
+// @return: node reference if success, NULL otherwise.
+// @throw: yes
+//
+tDirNodeReference CDirectoryServiceAuth::OpenNamedNode(const char* nodename)
+{
+	// Check cache first
+    tDirNodeReference result = NULL;
+	TNodeMap::const_iterator found = mNodeMap.find(nodename);
+	if (found != mNodeMap.end())
+	{
+		return (*found).second;
+	}
+	
+	// Create a new one and cache
+	result = CDirectoryService::OpenNamedNode(nodename);
+	mNodeMap[nodename] = result;
+    return result;
+}

Added: PyOpenDirectory/trunk/src/CDirectoryServiceAuth.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryServiceAuth.h	                        (rev 0)
+++ PyOpenDirectory/trunk/src/CDirectoryServiceAuth.h	2008-12-17 18:14:59 UTC (rev 3539)
@@ -0,0 +1,45 @@
+/**
+ * A class that wraps high-level Directory Service calls needed by the
+ * CalDAV server.
+ **
+ * Copyright (c) 2006-2008 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.
+ **/
+
+#pragma once
+
+#include "CDirectoryService.h"
+
+#include <map>
+
+class CDirectoryServiceAuth : public CDirectoryService
+{
+public:
+    CDirectoryServiceAuth();
+    virtual ~CDirectoryServiceAuth();
+
+    bool AuthenticateUserBasic(const char* nodename, const char* user, const char* pswd, bool& result, bool using_python=true);
+    bool AuthenticateUserDigest(const char* nodename, const char* user, const char* challenge, const char* response, const char* method, bool& result, bool using_python=true);
+
+protected:
+
+	typedef std::map<const char*, tDirNodeReference> TNodeMap;
+	TNodeMap mNodeMap;
+
+    bool NativeAuthenticationBasicToNode(const char* nodename, const char* user, const char* pswd);
+    bool NativeAuthenticationDigestToNode(const char* nodename, const char* user, const char* challenge, const char* response, const char* method);
+
+    virtual void CloseService();
+    virtual tDirNodeReference OpenNamedNode(const char* nodename);
+};

Modified: PyOpenDirectory/trunk/src/CDirectoryServiceManager.cpp
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryServiceManager.cpp	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/src/CDirectoryServiceManager.cpp	2008-12-17 18:14:59 UTC (rev 3539)
@@ -20,6 +20,7 @@
 #include "CDirectoryServiceManager.h"
 
 #include "CDirectoryService.h"
+#include "CDirectoryServiceAuth.h"
 #include "CDirectoryServiceException.h"
 
 #pragma mark -----Public API
@@ -27,10 +28,16 @@
 CDirectoryServiceManager::CDirectoryServiceManager(const char* nodename)
 {
     mNodeName = ::strdup(nodename);
+	mAuthService = NULL;
 }
 
 CDirectoryServiceManager::~CDirectoryServiceManager()
 {
+	if (mAuthService != NULL)
+	{
+		delete mAuthService;
+		mAuthService = NULL;
+	}
     ::free(mNodeName);
 }
 
@@ -38,3 +45,10 @@
 {
     return new CDirectoryService(mNodeName);
 }
+
+CDirectoryServiceAuth* CDirectoryServiceManager::GetAuthService()
+{
+	if (mAuthService == NULL)
+		mAuthService = new CDirectoryServiceAuth();
+    return mAuthService;
+}

Modified: PyOpenDirectory/trunk/src/CDirectoryServiceManager.h
===================================================================
--- PyOpenDirectory/trunk/src/CDirectoryServiceManager.h	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/src/CDirectoryServiceManager.h	2008-12-17 18:14:59 UTC (rev 3539)
@@ -20,6 +20,7 @@
 #pragma once
 
 class CDirectoryService;
+class CDirectoryServiceAuth;
 
 class CDirectoryServiceManager
 {
@@ -27,11 +28,10 @@
     CDirectoryServiceManager(const char* nodename);
     ~CDirectoryServiceManager();
 
-    void OpenService();
-    void CloseService();
-
     CDirectoryService* GetService();
+    CDirectoryServiceAuth* GetAuthService();
 
 private:
-    char*            mNodeName;
+    char*					mNodeName;
+	CDirectoryServiceAuth*	mAuthService;
 };

Modified: PyOpenDirectory/trunk/src/PythonWrapper.cpp
===================================================================
--- PyOpenDirectory/trunk/src/PythonWrapper.cpp	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/src/PythonWrapper.cpp	2008-12-17 18:14:59 UTC (rev 3539)
@@ -19,6 +19,7 @@
 
 #include "CDirectoryServiceManager.h"
 #include "CDirectoryService.h"
+#include "CDirectoryServiceAuth.h"
 #include "CFStringUtil.h"
 
 #include <memory>
@@ -789,7 +790,7 @@
     CDirectoryServiceManager* dsmgr = static_cast<CDirectoryServiceManager*>(PyCObject_AsVoidPtr(pyds));
     if (dsmgr != NULL)
     {
-        std::auto_ptr<CDirectoryService> ds(dsmgr->GetService());
+        CDirectoryServiceAuth* ds = dsmgr->GetAuthService();
         bool result = false;
         bool authresult = false;
         result = ds->AuthenticateUserBasic(nodename, user, pswd, authresult);
@@ -838,7 +839,7 @@
     CDirectoryServiceManager* dsmgr = static_cast<CDirectoryServiceManager*>(PyCObject_AsVoidPtr(pyds));
     if (dsmgr != NULL)
     {
-        std::auto_ptr<CDirectoryService> ds(dsmgr->GetService());
+        CDirectoryServiceAuth* ds = dsmgr->GetAuthService();
         bool result = false;
         bool authresult = false;
         result = ds->AuthenticateUserDigest(nodename, user, challenge, response, method, authresult);

Modified: PyOpenDirectory/trunk/test_auth.py
===================================================================
--- PyOpenDirectory/trunk/test_auth.py	2008-12-17 03:17:02 UTC (rev 3538)
+++ PyOpenDirectory/trunk/test_auth.py	2008-12-17 18:14:59 UTC (rev 3539)
@@ -138,6 +138,9 @@
         False,
         dsattributes.kDSStdRecordTypeUsers,
         [dsattributes.kDSNAttrMetaNodeLocation])
+    if not result:
+        print "Failed to get record for user: %s" % (username,)
+        return
     nodename = result[0][1][dsattributes.kDSNAttrMetaNodeLocation]
     
     expected = calcResponse(
@@ -188,6 +191,9 @@
         False,
         dsattributes.kDSStdRecordTypeUsers,
         [dsattributes.kDSNAttrMetaNodeLocation])
+    if not result:
+        print "Failed to get record for user: %s" % (username,)
+        return
     nodename = result[0][1][dsattributes.kDSNAttrMetaNodeLocation]
     
     for _ignore_x in xrange(attempts):
@@ -210,6 +216,6 @@
 
 od = opendirectory.odInit(search)
 
-doAuthBasic(user, pswd)
+#doAuthBasic(user, pswd)
 doAuthDigest(user, pswd, None, "md5")
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081217/55f0beb4/attachment-0001.html>


More information about the calendarserver-changes mailing list