diff -uNr CookieCrumbler/CookieCrumbler.py CookieCrumbler-dirk/CookieCrumbler.py
--- CookieCrumbler/CookieCrumbler.py	Mon Jun 14 18:34:36 2004
+++ CookieCrumbler-dirk/CookieCrumbler.py	Mon Jun 27 22:53:17 2005
@@ -18,6 +18,7 @@
 from base64 import encodestring, decodestring
 from urllib import quote, unquote
 import sys
+import md5
 
 from Acquisition import aq_inner, aq_parent
 from DateTime import DateTime
@@ -29,6 +30,8 @@
 from ZPublisher.HTTPRequest import HTTPRequest
 from OFS.Folder import Folder
 
+from urllib2 import urlopen, Request
+
 try:
     from zExceptions import Redirect
 except ImportError:
@@ -40,6 +43,7 @@
 ATTEMPT_NONE = 0       # No attempt at authentication
 ATTEMPT_LOGIN = 1      # Attempt to log in
 ATTEMPT_RESUME = 2     # Attempt to resume session
+ATTEMPT_TICKET = 3     # Attempt to authenticate via sso-ticket
 
 ModifyCookieCrumblers = 'Modify Cookie Crumblers'
 ViewManagementScreens = Permissions.view_management_screens
@@ -83,6 +87,10 @@
                     'label':'Use cookie paths to limit scope'},
                    {'id':'cache_header_value', 'type': 'string', 'mode':'w',
                     'label':'Cache-Control header value'},
+                   {'id':'mysap_cookie', 'type': 'string', 'mode':'w',
+                    'label':'Authentication ticket cookie name'},
+                   {'id':'ticket_verifier_url', 'type': 'string', 'mode':'w',
+                    'label':'Ticket Verifier URL'},
                    )
 
     auth_cookie = '__ac'
@@ -94,6 +102,8 @@
     logout_page = 'logged_out'
     local_cookie_path = 0
     cache_header_value = 'no-cache'
+    mysap_cookie = 'MYSAPSSO2'
+    ticket_verifier_url = 'http://localhost:4080/verify'
 
     security.declarePrivate('delRequestVar')
     def delRequestVar(self, req, name):
@@ -137,6 +147,24 @@
     def defaultExpireAuthCookie(self, resp, cookie_name):
         resp.expireCookie(cookie_name, path=self.getCookiePath())
 
+
+    security.declarePrivate('verifyTicket')
+    def verifyTicket( self, ticket ):
+        """ Verify Ticket with external verification service """
+
+        req = Request( self.ticket_verifier_url, data=ticket )
+        req.add_header( 'Cookie', '%s=%s;' % (self.mysap_cookie, ticket) )
+
+        try:
+            resp = urlopen(req)
+            result = resp.read()
+            print result
+            return TicketInfo(result)
+        except Exception, ex:
+            print ex
+            return None
+
+
     security.declarePrivate('modifyRequest')
     def modifyRequest(self, req, resp):
         """Copies cookie-supplied credentials to the basic auth fields.
@@ -162,11 +190,41 @@
                 # created it.  The user must be using basic auth.
                 raise CookieCrumblerDisabled
 
-            if req.has_key(self.pw_cookie) and req.has_key(self.name_cookie):
+	    ticket_info = None
+
+	    if req.has_key(self.mysap_cookie) and self.ticket_verifier_url:
+		cookie_val = req.get(self.mysap_cookie)
+		m = md5.new()
+		m.update(cookie_val)
+		cookie_hash = m.digest()
+
+		#print cookie_val
+
+		if req.SESSION.has_key(cookie_hash):
+		    #print "get ticket_info %s" % cookie_hash
+		    ticket_info = req.SESSION.get(cookie_hash)
+		else:
+		    ticket_info = self.verifyTicket(cookie_val)
+
+		    if ticket_info:
+			#print "set ticket_info %s" % cookie_hash
+		     	req.SESSION.set(cookie_hash, ticket_info)
+
+	    if ticket_info:
+		    name = ticket_info.getPortalUser()
+                    ac = encodestring('%s:__ssoticket__=%s' % (name,cookie_hash)).rstrip()
+                    req._auth = 'Basic %s' % ac
+                    resp._auth = 1
+                    #print req._auth
+                    #print name
+		    attempt = ATTEMPT_TICKET
+
+            elif req.has_key(self.pw_cookie) and req.has_key(self.name_cookie):
                 # Attempt to log in and set cookies.
                 attempt = ATTEMPT_LOGIN
                 name = req[self.name_cookie]
                 pw = req[self.pw_cookie]
+		if pw[:13] == '__ssoticket__': pw = None
                 ac = encodestring('%s:%s' % (name, pw)).rstrip()
                 req._auth = 'Basic %s' % ac
                 resp._auth = 1
@@ -221,12 +279,13 @@
             return
 
         if (self.unauth_page or
-            attempt == ATTEMPT_LOGIN or attempt == ATTEMPT_NONE):
+            attempt in [ATTEMPT_LOGIN, ATTEMPT_NONE, ATTEMPT_TICKET]):
             # Modify the "unauthorized" response.
             req._hold(ResponseCleanup(resp))
             resp.unauthorized = self.unauthorized
             resp._unauthorized = self._unauthorized
-        if attempt != ATTEMPT_NONE:
+
+        if attempt != ATTEMPT_NONE and attempt != ATTEMPT_TICKET:
             # Trying to log in or resume a session
             if self.cache_header_value:
                 # we don't want caches to cache the resulting page
@@ -289,6 +348,7 @@
         # Fall through to the standard _unauthorized() call.
         resp._unauthorized()
 
+
     security.declarePublic('getUnauthorizedURL')
     def getUnauthorizedURL(self):
         '''
@@ -372,6 +432,33 @@
         return id
 
 Globals.InitializeClass(CookieCrumbler)
+
+class TicketInfo:
+
+    def __init__(self, string):
+
+        items = string.split(';')
+
+        self.portalUser = items[0]
+        self.user = items[1]
+        self.system = items[2]
+        self.client = items[3]
+        self.valid = items[4]
+
+    def getPortalUser(self):
+        return self.portalUser
+
+    def getUser(self):
+        return self.user
+
+    def getSystem(self):
+        return self.system
+
+    def getClient(self):
+        return self.client
+
+    def isValid(self):
+        return isValid
 
 
 class ResponseCleanup:
