source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/SessionMgr/server-config.tac @ 2437

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/SessionMgr/server-config.tac@2437
Revision 2437, 7.9 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".

Line 
1#!/usr/bin/env python
2"""NDG Security Session Manager .tac file
3
4This file enables the Session Manager web service to be
5called under the Twisted framework
6
7NERC Data Grid Project
8
9@author P J Kershaw 23/11/06
10
11@copyright (C) 2007 CCLRC & NERC
12
13@license This software may be distributed under the terms of the Q Public
14License, version 1.0 or later.
15"""
16from ZSI.twisted.WSresource import WSResource
17from twisted.application import service, internet
18from twisted.web.server import Site
19from twisted.web.resource import Resource
20
21from SessionMgr_services_server import SessionMgrService
22from ndg.security.server.SessionMgr import SessionMgr
23from ndg.security.common.wsSecurity import WSSecurityHandlerChainFactory, \
24        WSSecurityHandler, SignatureHandler
25
26
27class SessionMgrServiceSub(SessionMgrService, WSResource):
28
29    # Add WS-Security handlers
30    factory = WSSecurityHandlerChainFactory
31       
32    def __init__(self):
33        '''Initialize Session Manager class - encapsulates inner workings
34        including session management and proxy delegation
35       
36        @type ps: ZSI ParsedSoap
37        @param ps: client SOAP message
38        @rtype: tuple
39        @return: request and response objects'''
40
41        WSResource.__init__(self) 
42        self.sm = SessionMgr()
43
44
45    def soap_addUser(self, ps, **kw):
46        '''Add a new user account
47       
48        @type ps: ZSI ParsedSoap
49        @param ps: client SOAP message
50        @rtype: tuple
51        @return: request and response objects'''
52
53        request, response = SessionMgrService.soap_addUser(self, ps)
54        return request, response
55
56
57    def soap_connect(self, ps, **kw):
58        '''Connect to Session Manager and create a user session
59       
60        @type ps: ZSI ParsedSoap
61        @param ps: client SOAP message
62        @rtype: tuple
63        @return: request and response objects'''
64
65        request, response = SessionMgrService.soap_connect(self, ps)
66
67        result = self.sm.connect(username=request.Username,
68                                                                 passphrase=request.Passphrase,
69                                                                 createServerSess=request.CreateServerSess,
70                                                                 getCookie=request.GetCookie)
71                                       
72        response.ProxyCert, response.ProxyPriKey, response.UserCert, \
73                response.Cookie = result
74                         
75        return request, response
76
77
78    def soap_disconnect(self, ps, **kw):
79        '''Disconnect and remove user's session
80       
81        @type ps: ZSI ParsedSoap
82        @param ps: client SOAP message
83        @rtype: tuple
84        @return: request and response objects'''
85           
86        request, response = SessionMgrService.soap_disconnect(self, ps)
87       
88        # Derive designated user ID differently according to whether
89        # a session ID was passed and the message was signed
90        if request.SessID:
91                sessID = request.SessID
92        else:
93                sessID = None
94               
95        if srv.sm['useSignatureHandler']:
96            # Get certificate corresponding to private key that signed the
97            # message - i.e. the user's proxy
98            userCert = WSSecurityHandler.signatureHandler.verifyingCert
99        else:
100            userCert = None
101       
102        self.sm.disconnect(sessID=sessID, proxyCert=userCert)
103        return request, response
104
105
106    def soap_getAttCert(self, ps, **kw):
107        '''Get Attribute Certificate from a given Attribute Authority
108        and cache it in user's Credential Wallet
109       
110        @type ps: ZSI ParsedSoap
111        @param ps: client SOAP message
112        @rtype: tuple
113        @return: request and response objects'''
114
115        request, response = SessionMgrService.soap_getAttCert(self, ps)
116       
117        # Get certificate corresponding to private key that signed the
118        # message - i.e. the user's             
119        if srv.sm['useSignatureHandler']:
120            # Get certificate corresponding to private key that signed the
121            # message - i.e. the user's proxy
122            userCert = WSSecurityHandler.signatureHandler.verifyingCert
123        else:
124            userCert = None
125       
126                # Cert used in signature is prefered over userCert input element -
127                # userCert may have been omitted.
128        result = self.sm.getAttCert(\
129                                            userCert=userCert or request.UserCert,
130                                                sessID=request.SessID,
131                                                encrSessMgrURI=request.EncrSessionMgrURI,
132                                                aaURI=request.AttAuthorityURI,
133                                                reqRole=request.ReqRole,
134                                                mapFromTrustedHosts=request.MapFromTrustedHosts,
135                                                rtnExtAttCertList=request.RtnExtAttCertList,
136                                                extAttCertList=request.ExtAttCert,
137                                                extTrustedHostList=request.ExtTrustedHost)
138
139
140        if result[0]:
141                response.AttCert = result[0].toString() 
142               
143        response.Msg, response.ExtAttCertOut = result[1:]
144       
145        return request, response
146
147
148    def soap_getX509Cert(self, ps, **kw):
149        '''Return Session Manager's X.509 certificate
150       
151        @type ps: ZSI ParsedSoap
152        @param ps: client SOAP message
153        @rtype: tuple
154        @return: request and response objects'''
155       
156        request, response = SessionMgrService.soap_getX509Cert(self, ps)
157        response.X509Cert = open(self.sm['certFile']).read().strip()
158        return request, response
159
160
161# Create Service
162srv = SessionMgrServiceSub()
163
164# Initialise WS-Security signature handler passing Session Manager
165# public and private keys
166WSSecurityHandler.signatureHandler = SignatureHandler(\
167                                                                verifyingCertFilePath=srv.sm['clntCertFile'],
168                                    signingCertFilePath=srv.sm['certFile'],
169                                    signingPriKeyFilePath=srv.sm['keyFile'],
170                                    signingPriKeyPwd=srv.sm['keyPwd'])
171
172# Add Service to Session Manager branch
173root = Resource()
174root.putChild('SessionManager', srv)
175siteFactory = Site(root)
176
177if srv.sm['useSSL']:
178        # Use SSL connection
179#       from twisted.internet import ssl
180#       
181#       # Nb. ssl.DefaultOpenSSLContextFactory requires pyOpenSSL
182#       ctxFactory = ssl.DefaultOpenSSLContextFactory(srv.sm['sslKeyFile'],
183#                                                                                                 srv.sm['sslCertFile'])
184#       port = internet.SSLServer(srv.sm['portNum'], siteFactory, ctxFactory)
185
186    # Using M2Crypto ...
187    import os
188    os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
189
190    import twisted.protocols.policies as policies
191    from M2Crypto import SSL
192    from M2Crypto.SSL import TwistedProtocolWrapper
193    from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
194       
195    siteFactory.startTLS = True
196    siteFactory.sslChecker = SSL.Checker.Checker()
197
198        # TODO: Python ssl client seems to require SSL vers 2 is this a security
199        # risk?
200    ctx = SSL.Context(protocol='sslv23')
201    ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
202    ctx.load_cert(srv.sm['sslCertFile'], 
203                          srv.sm['sslKeyFile'],
204                          callback=lambda *args, **kw: srv.aa['sslKeyPwd'])
205                         
206    ctx.set_allow_unknown_ca(False)
207
208    # TODO: resolve check - verify_peer setting fails with
209    # BIOError: 'no certificate returned' error 18
210#    ctx.set_verify(SSL.verify_peer, 10)
211    ctx.set_verify(SSL.verify_client_once, 1)
212
213    ctx.load_verify_locations(cafile=os.path.basename(srv.sm['caCertFile']), 
214                                                  capath=os.path.dirname(srv.sm['caCertFile']))
215
216    class ContextFactory:
217        def getContext(self):
218            return ctx
219
220    factory = policies.WrappingFactory(siteFactory)
221    factory.protocol.TLS = True
222    factory.protocol = lambda factory, wrappedProtocol: \
223        TLSProtocolWrapper(factory,
224                           wrappedProtocol,
225                           startPassThrough=0,
226                           client=0,
227                           contextFactory=ContextFactory(),
228                           postConnectionCheck=None)
229
230    siteFactory = factory
231   
232    port = internet.TCPServer(srv.sm['portNum'], siteFactory)
233    port.CERTFILE = srv.sm['sslCertFile']
234    port.KEYFILE = srv.sm['sslKeyFile']
235    root.__class__.server = port
236else:   
237        # Non-SSL
238        port = internet.TCPServer(srv.sm['portNum'], siteFactory)
239
240application = service.Application("SessionManagerContainer")
241port.setServiceParent(application)
Note: See TracBrowser for help on using the repository browser.