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

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

ndg.security.server/ndg/security/server/Log.py: remove ref to 'Logger'

ndg.security.server/ndg/security/server/SessionMgr/server-config.tac:
added M2Crypto SSL support

ndg.security.server/ndg/security/server/SessionMgr/start-container.sh:
copy from Attribute Authority version.

ndg.security.test/ndg/security/test/SessionMgr/SessionMgrClientTest.py:
fix to test5ProxyCertDisconnect call.

ndg.security.test/ndg/security/test/SessionMgr/sessionMgrClientTest.cfg:
set clntprikeypwd to null so that it is not prompted for from terminal.

ndg.security.common/ndg/security/common/SessionMgr/init.py: fix to
disconnect SOAP client call so that userCert omit alone is allowed.

ndg.security.common/ndg/security/common/wsSecurity.py: delete debug call.

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