source: TI12-security/trunk/python/ndg.security.common/ndg/security/common/SessionMgr/__init__.py @ 2076

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.common/ndg/security/common/SessionMgr/__init__.py@2076
Revision 2076, 15.5 KB checked in by pjkersha, 13 years ago (diff)

python/ndg.security.server/ndg/security/server/SessionMgr/server-config.tac:

  • Added code to soap_getAttCert stub
  • updated WSSecurityHandler.signatureHandler initialisation with new keywords.

python/ndg.security.server/ndg/security/server/SessionMgr/init.py:

  • renamed redirectAuthorisationReq -> redirectAttCertReq
  • createUserSession now takes proxy cert, private key and user cert as inputs

python/www/html/sessionMgr.wsdl,
python/ndg.security.server/ndg/security/server/SessionMgr/SessionMgr_services_server.py,
python/ndg.security.common/ndg/security/common/SessionMgr/SessionMgr_services.py and
python/ndg.security.common/ndg/security/common/SessionMgr/SessionMgr_services_types.py:
Modified getAttCert and disconnect operations.

python/ndg.security.test/ndg/security/test/SessionMgr/SessionMgrClientTest.py:

  • updated call to SessionMgrClient? to use new SignatureHandler? keywords.
  • experimenting with disconnect calls - signature doesn't verify correctly at server side.
  • updated call to getAttcert in test6CookieGetAttCert

python/ndg.security.test/ndg/security/test/SessionMgr/sessionMgrClientTest.cfg: updated
AA URIs.

python/ndg.security.common/ndg/security/common/AttAuthority/init.py:
added getSignatureHandler property access method.

python/ndg.security.common/ndg/security/common/XMLSec.py: include more info about error
for when RSA pub key verify fails.

python/ndg.security.common/ndg/security/common/wsSecurity.py:

  • added InvalidSignature? type exception
  • include more info about error for when RSA pub key verify fails.

python/ndg.security.common/ndg/security/common/SessionMgr/init.py:

  • added getSignatureHandler property access method.
  • fix to disconnect keywords input check

python/ndg.security.common/ndg/security/common/CredWallet.py: major refactoring for
prospective beta release of NDG security -

  • attCertRefreshElapse - new attribute used by getAttCert to determine whether to replace

an existing AC in the cache with a fresh one. If the existing one has less than
attCertRefreshElapse time in seconds left before expiry then replace it

  • added epydoc formatting
  • explicit proxy cert, private key and user cert inputs to init. These are also

declared as properties with access methods.

  • proxy cert / private key used in SOAP message signatures.
  • use NullCredRepos? class as default Credential Repository
  • refactoring of WS calls to AA in line with new AttAuthorityClient? interface.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/env python
2"""NDG Security client - client interface classes to Session Manager
3
4Make requests for authentication and authorisation
5
6NERC Data Grid Project
7
8P J Kershaw 24/04/06
9
10Copyright (C) 2006 CCLRC & NERC
11
12This software may be distributed under the terms of the Q Public License,
13version 1.0 or later.
14"""
15__all__ = ['SessionMgr_services', 'SessionMgr_services_types']
16
17import sys
18import os
19
20# Handle retrieval of public key cert for Session Manager/Attribute Authority
21# at remote location
22import tempfile
23import urllib
24
25from ndg.security.common.SessionCookie import SessionCookie
26from ndg.security.common.wsSecurity import SignatureHandler
27from ndg.security.common.X509 import *
28from ndg.security.common.AttCert import AttCertParse
29from SessionMgr_services import SessionMgrServiceLocator
30
31
32#_____________________________________________________________________________
33class SessionMgrClientError(Exception):
34    """Exception handling for SessionMgrClient class"""
35
36#_____________________________________________________________________________       
37class SessionMgrClient(object):
38    """Client interface to Session Manager Web Service"""
39   
40    #_________________________________________________________________________
41    def __init__(self, uri=None, tracefile=None, **signatureHandlerKw):
42        """
43        @type uri: string
44        @keyword uri: URI for Session Manager WS.  Setting it will set the
45        Service Proxy
46               
47        @type tracefile: file stream type
48        @param tracefile: set to file object such as sys.stderr to give extra
49        WS debug information
50       
51        @type signatureHandlerKw: dict
52        @param signatureHandlerKw: keywords to configure signature handler"""
53
54        self.__srv = None
55        self.__uri = None
56       
57        self.__srvCertTempFile = None
58       
59       
60        if uri:
61            self.__setURI(uri)
62
63        # WS-Security Signature handler
64        self.__signatureHandler = SignatureHandler(**signatureHandlerKw)
65       
66        self.__tracefile = tracefile
67
68         
69        # Instantiate Session Manager WS ZSI client
70        if self.__uri:
71            self.initService()
72       
73
74    #_________________________________________________________________________
75    def __setURI(self, uri):
76        "Set URI property method"
77       
78        if not isinstance(uri, basestring):
79            raise SessionMgrClientError, \
80                             "Session Manager WSDL URI must be a valid string"
81       
82        self.__uri = uri
83       
84    uri = property(fset=__setURI, doc="Set Session Manager URI")
85
86
87    #_________________________________________________________________________
88    def __getSignatureHandler(self):
89        "Get SignatureHandler object property method"
90        return self.__signatureHandler
91   
92    signatureHandler = property(fget=__getSignatureHandler,
93                                doc="SignatureHandler object")
94   
95   
96    #_________________________________________________________________________
97    def __getSrvX509Cert(self):
98        """Retrieve the X.509 certificate from file or if not available, from
99        the Session Manager service"""
100       
101        # Don't proceed unless URI was set - user may have set public key via
102        # srvCertFilePath instead
103        if self.__srvCertFilePath is not None:
104            return
105               
106        try:
107            self.__srvCertTempFile = tempfile.NamedTemporaryFile()
108           
109            cert = self.getX509Cert()
110            open(self.__srvCertTempFile.name, "w").write(cert)
111           
112            self.__srvCertFilePath = self.__srvCertTempFile.name
113           
114        except IOError, (errNo, errMsg):
115            raise SessionMgrClientError, \
116                            "Writing X.509 certificate to temp \"%s\": %s" % \
117                            (self.__srvCertTempFile.name, errMsg)                                                                   
118        except Exception, e:
119            raise SessionMgrClientError, "Retrieving Session Manager " + \
120                                         "X.509 certificate: %s" % str(e)
121   
122       
123    #_________________________________________________________________________
124    def initService(self, uri=None):
125        """Set the WS client for the Session Manager"""
126        if uri:
127            self.__setURI(uri)
128   
129        # WS-Security Signature handler object is passed to binding
130        try:
131            locator = SessionMgrServiceLocator()
132            self.__srv = locator.getSessionMgr(self.__uri,
133                                       sig_handler=self.__signatureHandler,
134                                       tracefile=self.__tracefile)
135        except HTTPResponse, e:
136            raise SessionMgrClientError, \
137                "Initialising Service for \"%s\": %s %s" % \
138                (self.__uri, e.status, e.reason)
139           
140        except Exception, e:
141            raise SessionMgrClientError, \
142                "Initialising Service for \"%s\": %s" % (self.__uri, str(e))
143
144                                   
145    #_________________________________________________________________________
146    def addUser(self,
147                username,
148                passphrase=None,
149                passphraseFilePath=None,
150                clntPriKeyPwd=None):
151        """Register a new user
152       
153        username:                the username for the new user
154        passphrase:                 user's pass-phrase
155        passphraseFilePath:         a file containing the user's pass-phrase. 
156                                 Use this as an alternative to passphrase keyword
157        clntPriKeyPwd:           pass-phrase if any for the client's private
158                                 key used to decrypt response from
159                                 Session Manager
160        """
161   
162        if passphrase is None:
163            try:
164                passphrase = open(passphraseFilePath).read().strip()
165           
166            except Exception, e:
167                raise SessionMgrClientError, "Pass-phrase not defined: " + \
168                                            str(e)
169           
170   
171        # Make request for new user
172        try:   
173            self.__srv.addUser(username, passphrase)
174
175        except Exception, e:
176            raise SessionMgrClientError, "Adding new user: " + str(e)
177   
178       
179    #_________________________________________________________________________   
180    def connect(self,
181                username,
182                passphrase=None,
183                passphraseFilePath=None,
184                getCookie=False,
185                createServerSess=True):
186        """Request a new user session from the Session Manager
187       
188        @type username: string
189        @param username: the username of the user to connect
190       
191        @type passphrase: string
192        @keyword passphrase: user's pass-phrase
193       
194        @type passphraseFilePath: string
195        @keyword passphraseFilePath: a file containing the user's pass-phrase. 
196        Use this as an alternative to passphrase keyword.
197                                 
198        @type getCookie: bool
199        @keyword getCookie: If set to True, return a cookie to be set in
200        a web browser client. 
201                                 
202        @type createServerSess: bool
203        @keyword createServerSess: If set to True, the SessionMgr will create
204        and manage a session for the user but note, this flag is ignored and
205        set to True if getCookie is set.  For command line case, where
206        getCookie is False, it's possible to choose to have a client or server
207        side session using this keyword.
208       
209        @rtype: tuple
210        @return proxy cert, proxy private key, user cert and cookie all as
211        strings but cookie will be None if the getCookie keyword is False"""
212   
213        if passphrase is None:
214            try:
215                passphrase = open(passphraseFilePath).read().strip()
216           
217            except Exception, e:
218                raise SessionMgrClientError, "Pass-phrase not defined: " + \
219                                             str(e)
220
221        # Make connection
222        try: 
223            userID = self.__srv.connect(username, 
224                                        passphrase,
225                                        createServerSess,
226                                        getCookie)
227            return userID
228               
229        except Exception, e:
230            raise SessionMgrClientError, \
231                                    "Connecting to Session Manager: " + str(e)
232   
233       
234    #_________________________________________________________________________   
235    def disconnect(self,
236                   userCert=None,
237                   sessCookie=None,
238                   sessID=None,
239                   encrSessionMgrURI=None):
240        """Delete an existing user session from the Session Manager
241       
242        disconnect([sessCookie=s]|[sessID=i, encrSessionMgrURI=e]|
243                   [userCert=u][key=arg, ...])
244                   
245        @type userCert:
246        @keyword userCert: proxy certificate - use as ID instead of a cookie
247        in the case of a command line client.
248       
249        @type sessCookie: ndg.security.common.SessionCookie or string                 
250        @keyword sessCookie: session cookie returned from call to connect()
251        for a browser client. 
252                               
253        @type sessID: string
254        @keyword sessID: session ID.  Input this as well as encrSessionMgrURI
255        as an alternative to sessCookie in the case of a browser client.
256       
257        @type encrSessionMgrURI: string
258        @keyword encrSessionMgrURI: encrypted Session Manager URI."""
259
260        # Checking authentication details: either a proxy cert,
261        # session cookie, or session ID/encrypted Session Manager URI
262        # combination
263        if sessCookie:
264            if isinstance(sessCookie, basestring):
265                try:
266                    sessCookie = SessionCookie(sessCookie)
267                except Exception, e:
268                    raise SessionMgrClientError, \
269                                    "Error parsing session cookie: " + str(e)
270
271            sessID = sessCookie.sessionID
272            encrSessionMgrURI = sessCookie.encrSessionMgrURI
273           
274        elif not sessID and not encrSessionMgrURI:
275            raise SessionMgrClientError, '"sessCookie or "sessID" and ' + \
276                                '"encrSessionMgrURI" keywords must be set'
277
278        # Make connection
279        try: 
280            self.__srv.disconnect(userCert, sessID, encrSessionMgrURI)
281               
282        except Exception, e:
283            raise SessionMgrClientError, \
284                        "Disconnecting from Session Manager: " + str(e)
285   
286   
287    #_________________________________________________________________________
288    def getAttCert(self,
289                   proxyCert=None,
290                   sessCookie=None,
291                   sessID=None,
292                   encrSessionMgrURI=None,
293                   attAuthorityURI=None,
294                   attAuthorityCert=None,
295                   reqRole=None,
296                   mapFromTrustedHosts=True,
297                   rtnExtAttCertList=False,
298                   extAttCertList=[],
299                   extTrustedHostList=[]):   
300        """Request NDG Session Manager Web Service to retrieve an Attribute
301        Certificate from the given Attribute Authority and cache it in the
302        user's credential wallet held by the session manager.
303       
304        reqAuthorisation([sessCookie=s]|[sessID=i, encrSessionMgrURI=e]|
305                         [proxyCert=p][key=arg, ...])
306        proxyCert:             proxy certificate - use as ID instead of
307                               a cookie in the case of a command line client.
308        sessCookie:            session cookie returned from call to connect()
309                               for a browser client.  Input as a string or
310                               SimpleCookie type.
311        sessID:                session ID.  Input this as well as
312                               encrSessionMgrURI as an alternative to
313                               sessCookie in the case of a browser client.
314        encrSessionMgrURI:     encrypted Session Manager URI.
315        attAuthorityURI:       URI for Attribute Authority WS.
316        attAuthorityCert:      The Session Manager uses the Public key of the
317                               Attribute Authority to encrypt requests to it.
318        reqRole:               The required role for access to a data set.
319                               This can be left out in which case the
320                               Attribute Authority just returns whatever
321                               Attribute Certificate it has for the user
322        mapFromTrustedHosts:   Allow a mapped Attribute Certificate to be
323                               created from a user certificate from another
324                               trusted host.
325        rtnExtAttCertList:     Set this flag True so that if authorisation is
326                               denied, a list of potential attribute
327                               certificates for mapping may be returned.
328        extAttCertList:        A list of Attribute Certificates from other
329                               trusted hosts from which the target Attribute
330                               Authority can make a mapped certificate
331        extTrustedHostList:    A list of trusted hosts that can be used to
332                               get Attribute Certificates for making a mapped
333                               AC.
334        """
335       
336        # Checking authentication details: either a proxy cert,
337        # session cookie, or session ID/encrypted Session Manager URI
338        # combination
339        if sessCookie:
340            if isinstance(sessCookie, basestring):
341                try:
342                    sessCookie = SessionCookie(sessCookie)
343                except Exception, e:
344                    raise SessionMgrClientError, \
345                                    "Error parsing session cookie: " + str(e)
346
347            sessID = sessCookie.sessionID
348            encrSessionMgrURI = sessCookie.encrSessionMgrURI
349           
350        elif not sessID and not encrSessionMgrURI and not proxyCert:
351            raise SessionMgrClientError, \
352                '"proxyCert" or "sessCookie or "sessID" and ' + \
353                '"encrSessionMgrURI" keywords must be set'
354
355           
356        # Make request
357        try:
358            result = self.__srv.getAttCert(proxyCert,
359                                           sessID, 
360                                           encrSessionMgrURI,
361                                           attAuthorityURI,
362                                           attAuthorityCert,
363                                           reqRole,
364                                           mapFromTrustedHosts,
365                                           rtnExtAttCertList,
366                                           extAttCertList,
367                                           extTrustedHostList)
368            return result
369           
370        except Exception, e:
371            raise SessionMgrClientError, \
372                                "Attribute Certificate request: " + str(e)
373
374                                   
375    #_________________________________________________________________________
376    def getX509Cert(self):
377        """Retrieve the public key of the Session Manager"""
378       
379        try:   
380            resp = self.__srv.getX509Cert()
381            return resp
382       
383        except Exception, e:
384            raise SessionMgrClientError, "Retrieving X.509 certificate: " + \
385                                         str(e)
386                           
Note: See TracBrowser for help on using the repository browser.