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

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

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

  • soap_disconnect: added call to SessionMgr?.disconnect, added logic for retrieving ID from cert.

used with WS-Security signature.

  • add code to check for useSignatureHandler config param. If this flag is set, get user ID from

cert in WS-Security header

ndg.security.test/ndg/security/test/SessionMgr/sessionMgrProperties.xml,
ndg.security.server/ndg/security/server/SessionMgr/init.py: added "useSignatureHandler" parameter
to properties file elements.

www/html/sessionMgr.wsdl,
ndg.security.server/ndg/security/server/SessionMgr/SessionMgr_services_server.py,
ndg.security.common/ndg/security/common/SessionMgr/SessionMgr_services.py,
ndg.security.common/ndg/security/common/SessionMgr/SessionMgr_services_types.py: removed userCert
argument. - This is not needed as cert chain can be passed in by setting #X509PKIPathv1 for
BinarySecurityToken?.

ndg.security.client/ndg/security/client/ndgSessionClient.py: started on updates from alpha version -
--req-autho flag is now --req-attr

ndg.security.test/ndg/security/test/AttCert/attCertTest.cfg,
ndg.security.test/ndg/security/test/AttCert/attCertTest.cfg: added more tests for signature
verification tests.

ndg.security.test/ndg/security/test/SessionMgr/SessionMgrClientTest.py: removed userCert arg from
disconnect call. It's passed in the signature in the WS-Security header.

ndg.security.common/ndg/security/common/XMLSec.py: fixed bug in applyEnvelopedSignature - removed
incorrect strip call from digest calc:

calcSignedInfoDigestValue = sha(signedInfoC14n).digest()#.strip()


ndg.security.common/ndg/security/common/SessionMgr/init.py: Session Manager client code -
remove refs to "userCert" for disconnect and connect calls. It's passed in the WS-Security header
instead.

ndg.security.common/ndg/security/common/wsSecurity.py: comment - query whitespace strip in
extraction of calculated signature value from message "b64EncSignatureValue".

  • 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                   sessCookie=None,
241                   sessID=None,
242                   encrSessionMgrURI=None):
243        """Delete an existing user session from the Session Manager
244       
245        disconnect([sessCookie=s]|[sessID=i, encrSessionMgrURI=e])
246       
247        @type sessCookie: ndg.security.common.SessionCookie or string                 
248        @keyword sessCookie: session cookie returned from call to connect()
249        for a browser client. 
250                               
251        @type sessID: string
252        @keyword sessID: session ID.  Input this as well as encrSessionMgrURI
253        as an alternative to sessCookie in the case of a browser client.
254       
255        @type encrSessionMgrURI: string
256        @keyword encrSessionMgrURI: encrypted Session Manager URI."""
257
258        # Checking authentication details: either a proxy cert,
259        # session cookie, or session ID/encrypted Session Manager URI
260        # combination
261        if sessCookie:
262            if isinstance(sessCookie, basestring):
263                try:
264                    sessCookie = SessionCookie(sessCookie)
265                except Exception, e:
266                    raise SessionMgrClientError, \
267                                    "Error parsing session cookie: " + str(e)
268
269            sessID = sessCookie.sessionID
270            encrSessionMgrURI = sessCookie.encrSessionMgrURI
271
272        # Make connection
273        try: 
274            self.__srv.disconnect(sessID, encrSessionMgrURI)
275               
276        except Exception, e:
277            raise SessionMgrClientError, \
278                        "Disconnecting from Session Manager: " + str(e)
279   
280   
281    #_________________________________________________________________________
282    def getAttCert(self,
283                   proxyCert=None,
284                   sessCookie=None,
285                   sessID=None,
286                   encrSessionMgrURI=None,
287                   attAuthorityURI=None,
288                   attAuthorityCert=None,
289                   reqRole=None,
290                   mapFromTrustedHosts=True,
291                   rtnExtAttCertList=False,
292                   extAttCertList=[],
293                   extTrustedHostList=[]):   
294        """Request NDG Session Manager Web Service to retrieve an Attribute
295        Certificate from the given Attribute Authority and cache it in the
296        user's credential wallet held by the session manager.
297       
298        getAttCert([sessCookie=s]|[sessID=i, encrSessionMgrURI=e]|
299                   [proxyCert=p][key=arg, ...])
300                   
301        proxyCert:             proxy certificate - use as ID instead of
302                               a cookie in the case of a command line client.
303        sessCookie:            session cookie returned from call to connect()
304                               for a browser client.  Input as a string or
305                               SimpleCookie type.
306        sessID:                session ID.  Input this as well as
307                               encrSessionMgrURI as an alternative to
308                               sessCookie in the case of a browser client.
309        encrSessionMgrURI:     encrypted Session Manager URI.
310        attAuthorityURI:       URI for Attribute Authority WS.
311        attAuthorityCert:      The Session Manager uses the Public key of the
312                               Attribute Authority to encrypt requests to it.
313        reqRole:               The required role for access to a data set.
314                               This can be left out in which case the
315                               Attribute Authority just returns whatever
316                               Attribute Certificate it has for the user
317        mapFromTrustedHosts:   Allow a mapped Attribute Certificate to be
318                               created from a user certificate from another
319                               trusted host.
320        rtnExtAttCertList:     Set this flag True so that if authorisation is
321                               denied, a list of potential attribute
322                               certificates for mapping may be returned.
323        extAttCertList:        A list of Attribute Certificates from other
324                               trusted hosts from which the target Attribute
325                               Authority can make a mapped certificate
326        extTrustedHostList:    A list of trusted hosts that can be used to
327                               get Attribute Certificates for making a mapped
328                               AC.
329        """
330       
331        # Checking authentication details: either a proxy cert,
332        # session cookie, or session ID/encrypted Session Manager URI
333        # combination
334        if sessCookie:
335            if isinstance(sessCookie, basestring):
336                try:
337                    sessCookie = SessionCookie(sessCookie)
338                except Exception, e:
339                    raise SessionMgrClientError, \
340                                    "Error parsing session cookie: " + str(e)
341
342            sessID = sessCookie.sessionID
343            encrSessionMgrURI = sessCookie.encrSessionMgrURI
344           
345        elif not sessID and not encrSessionMgrURI and not proxyCert:
346            raise SessionMgrClientError, \
347                '"proxyCert" or "sessCookie or "sessID" and ' + \
348                '"encrSessionMgrURI" keywords must be set'
349
350           
351        # Make request
352        try:
353            attCert, msg, extAttCertList = self.__srv.getAttCert(proxyCert,
354                                                       sessID, 
355                                                       encrSessionMgrURI,
356                                                       attAuthorityURI,
357                                                       attAuthorityCert,
358                                                       reqRole,
359                                                       mapFromTrustedHosts,
360                                                       rtnExtAttCertList,
361                                                       extAttCertList,
362                                                       extTrustedHostList)
363        except Exception, e:
364            raise SessionMgrClientError, \
365                                "Attribute Certificate request: " + str(e)
366        if not attCert:
367            raise AttributeRequestDenied, msg
368       
369        return attCert, extAttCertList
370   
371                                   
372    #_________________________________________________________________________
373    def getX509Cert(self):
374        """Retrieve the public key of the Session Manager"""
375       
376        try:   
377            resp = self.__srv.getX509Cert()
378            return resp
379       
380        except Exception, e:
381            raise SessionMgrClientError, "Retrieving X.509 certificate: " + \
382                                         str(e)
383                           
Note: See TracBrowser for help on using the repository browser.