[CalendarServer-changes] [1509]
PyOpenDirectory/branches/users/cdaboo/better-errors-1318/test_auth.
py
source_changes at macosforge.org
source_changes at macosforge.org
Wed May 2 12:19:42 PDT 2007
Revision: 1509
http://trac.macosforge.org/projects/calendarserver/changeset/1509
Author: cdaboo at apple.com
Date: 2007-05-02 12:19:42 -0700 (Wed, 02 May 2007)
Log Message:
-----------
Stress test DS authentication for basic and digest.
Added Paths:
-----------
PyOpenDirectory/branches/users/cdaboo/better-errors-1318/test_auth.py
Added: PyOpenDirectory/branches/users/cdaboo/better-errors-1318/test_auth.py
===================================================================
--- PyOpenDirectory/branches/users/cdaboo/better-errors-1318/test_auth.py (rev 0)
+++ PyOpenDirectory/branches/users/cdaboo/better-errors-1318/test_auth.py 2007-05-02 19:19:42 UTC (rev 1509)
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+
+from getpass import getpass
+import opendirectory
+import dsattributes
+import md5
+import sha
+
+algorithms = {
+ 'md5': md5.new,
+ 'md5-sess': md5.new,
+ 'sha': sha.new,
+}
+
+# DigestCalcHA1
+def calcHA1(
+ pszAlg,
+ pszUserName,
+ pszRealm,
+ pszPassword,
+ pszNonce,
+ pszCNonce,
+ preHA1=None
+):
+ """
+ @param pszAlg: The name of the algorithm to use to calculate the digest.
+ Currently supported are md5 md5-sess and sha.
+
+ @param pszUserName: The username
+ @param pszRealm: The realm
+ @param pszPassword: The password
+ @param pszNonce: The nonce
+ @param pszCNonce: The cnonce
+
+ @param preHA1: If available this is a str containing a previously
+ calculated HA1 as a hex string. If this is given then the values for
+ pszUserName, pszRealm, and pszPassword are ignored.
+ """
+
+ if (preHA1 and (pszUserName or pszRealm or pszPassword)):
+ raise TypeError(("preHA1 is incompatible with the pszUserName, "
+ "pszRealm, and pszPassword arguments"))
+
+ if preHA1 is None:
+ # We need to calculate the HA1 from the username:realm:password
+ m = algorithms[pszAlg]()
+ m.update(pszUserName)
+ m.update(":")
+ m.update(pszRealm)
+ m.update(":")
+ m.update(pszPassword)
+ HA1 = m.digest()
+ else:
+ # We were given a username:realm:password
+ HA1 = preHA1.decode('hex')
+
+ if pszAlg == "md5-sess":
+ m = algorithms[pszAlg]()
+ m.update(HA1)
+ m.update(":")
+ m.update(pszNonce)
+ m.update(":")
+ m.update(pszCNonce)
+ HA1 = m.digest()
+
+ return HA1.encode('hex')
+
+# DigestCalcResponse
+def calcResponse(
+ HA1,
+ algo,
+ pszNonce,
+ pszNonceCount,
+ pszCNonce,
+ pszQop,
+ pszMethod,
+ pszDigestUri,
+ pszHEntity,
+):
+ m = algorithms[algo]()
+ m.update(pszMethod)
+ m.update(":")
+ m.update(pszDigestUri)
+ if pszQop == "auth-int":
+ m.update(":")
+ m.update(pszHEntity)
+ HA2 = m.digest().encode('hex')
+
+ m = algorithms[algo]()
+ m.update(HA1)
+ m.update(":")
+ m.update(pszNonce)
+ m.update(":")
+ if pszNonceCount and pszCNonce and pszQop:
+ m.update(pszNonceCount)
+ m.update(":")
+ m.update(pszCNonce)
+ m.update(":")
+ m.update(pszQop)
+ m.update(":")
+ m.update(HA2)
+ respHash = m.digest().encode('hex')
+ return respHash
+
+
+attempts = 100
+
+realm = "/Search"
+nonce = "128446648710842461101646794502"
+nc = "00000001"
+cnonce = "0a4f113b12345"
+uri = "/principals/"
+method = "GET"
+
+def doAuthDigest(username, password, qop, algorithm):
+ failures = 0
+
+ result = opendirectory.queryRecordsWithAttribute(
+ od,
+ dsattributes.kDSNAttrRecordName,
+ username,
+ dsattributes.eDSExact,
+ False,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID])
+ guid = result[username][dsattributes.kDS1AttrGeneratedUID]
+
+ expected = calcResponse(
+ calcHA1(algorithm, username, realm, password, nonce, cnonce),
+ algorithm, nonce, nc, cnonce, qop, method, uri, None
+ )
+ #print expected
+
+ if qop:
+ challenge = 'Digest realm="%s", nonce="%s", algorithm=%s, qop="%s"' % (realm, nonce, algorithm, qop,)
+ else:
+ challenge = 'Digest realm="%s", nonce="%s", algorithm=%s' % (realm, nonce, algorithm,)
+ if qop:
+ response = ('Digest username="%s", realm="%s", '
+ 'nonce="%s", digest-uri="%s", '
+ 'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' % (username, realm, nonce, uri, expected, algorithm, cnonce, qop, nc, ))
+ else:
+ response = ('Digest username="%s", realm="%s", '
+ 'nonce="%s", digest-uri="%s", '
+ 'response=%s, algorithm=%s' % (username, realm, nonce, uri, expected, algorithm, ))
+
+ print " Challenge: %s" % (challenge,)
+ print " Response: %s" % (response, )
+
+ for x in xrange(attempts):
+ success = opendirectory.authenticateUserDigest(
+ od,
+ guid,
+ username,
+ challenge,
+ response,
+ method
+ )
+
+ if not success:
+ failures += 1
+
+ print "\n%d failures out of %d attempts for Digest.\n\n" % (failures, attempts)
+
+def doAuthBasic(username, password):
+ failures = 0
+
+ result = opendirectory.queryRecordsWithAttribute(
+ od,
+ dsattributes.kDSNAttrRecordName,
+ username,
+ dsattributes.eDSExact,
+ False,
+ dsattributes.kDSStdRecordTypeUsers,
+ [dsattributes.kDS1AttrGeneratedUID])
+ guid = result[username][dsattributes.kDS1AttrGeneratedUID]
+
+ for x in xrange(attempts):
+ success = opendirectory.authenticateUserBasic(
+ od,
+ guid,
+ username,
+ password,
+ )
+
+ if not success:
+ failures += 1
+
+ print "\n%d failures out of %d attempts for Basic.\n\n" % (failures, attempts)
+
+search = raw_input("DS search path: ")
+user = raw_input("User: ")
+pswd = getpass("Password: ")
+
+od = opendirectory.odInit(search)
+
+doAuthBasic(user, pswd)
+doAuthDigest(user, pswd, None, "md5")
+#doAuth(user, pswd, "auth", "md5")
+#doAuth(user, pswd, "auth", "md5-sess")
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070502/38e1b3b9/attachment.html
More information about the calendarserver-changes
mailing list