source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/conf/sessionMgr.tac @ 4120

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/conf/sessionMgr.tac@4120
Revision 4120, 9.4 KB checked in by pjkersha, 11 years ago (diff)

Fix for ndg.security.test.sessionMgr.test.SessionMgrTestCase?.test1Connect: use asPEM method to convert self.userCert to a string for output to file.

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"
10__date__ = "23/11/06"
11__copyright__ = "(C) 2007 STFC & NERC"
12__license__ = \
13"""This software may be distributed under the terms of the Q Public
14License, version 1.0 or later."""
15__contact__ = "P.J.Kershaw@rl.ac.uk"
16__revision__ = '$Id$'
17
18import os, base64
19
20from logging.config import fileConfig
21try:
22        _logConfig = os.path.join(os.environ["NDGSEC_DIR"],
23                                                          'conf',
24                                                          'sessionMgrLog.cfg')
25        fileConfig(_logConfig)
26
27except KeyError:
28        from warnings import warn
29        warn(\
30        '"NDGSEC_DIR" environment variable must be set to enable logging config',
31        RuntimeWarning)
32       
33import logging
34log = logging.getLogger(__name__)
35
36from ZSI.twisted.WSresource import WSResource
37from twisted.application import service, internet
38from twisted.web.server import Site
39from twisted.web.resource import Resource
40
41from ndg.security.server.SessionMgr.SessionMgr_services_server import \
42        SessionMgrService as _SessionMgrService
43from ndg.security.server.SessionMgr import SessionMgr
44from ndg.security.common.wsSecurity import SignatureHandler
45from ndg.security.server.twisted import WSSecurityHandler, \
46        WSSecurityHandlerChainFactory
47       
48
49from ndg.security.common.X509 import X509CertRead
50
51
52class SessionMgrService(_SessionMgrService, WSResource):
53
54    # Add WS-Security handlers
55    factory = WSSecurityHandlerChainFactory
56       
57    def __init__(self):
58        '''Initialize Session Manager class - encapsulates inner workings
59        including session management and proxy delegation
60       
61        @type ps: ZSI ParsedSoap
62        @param ps: client SOAP message
63        @rtype: tuple
64        @return: request and response objects'''
65       
66        # Stop in debugger at beginning of SOAP stub if environment variable
67        # is set
68        self.__debug = bool(os.environ.get('NDGSEC_INT_DEBUG'))
69        if self.__debug:
70                import pdb
71                pdb.set_trace()
72
73        WSResource.__init__(self) 
74        self.sm = SessionMgr()
75
76
77    def soap_connect(self, ps, **kw):
78        '''Connect to Session Manager and create a user session
79       
80        @type ps: ZSI ParsedSoap
81        @param ps: client SOAP message
82        @rtype: tuple
83        @return: request and response objects'''
84
85        if self.__debug:
86                import pdb
87                pdb.set_trace()
88               
89        request, response = _SessionMgrService.soap_connect(self, ps)
90       
91        result = self.sm.connect(username=request.Username,
92                                                                 passphrase=request.Passphrase,
93                                                                 createServerSess=request.CreateServerSess)
94                                       
95        response.UserCert, response.UserPriKey, response.issuingCert, \
96                response.SessID = result
97                         
98        return request, response
99
100
101    def soap_disconnect(self, ps, **kw):
102        '''Disconnect and remove user's session
103       
104        @type ps: ZSI ParsedSoap
105        @param ps: client SOAP message
106        @rtype: tuple
107        @return: request and response objects'''
108        if self.__debug:
109                import pdb
110                pdb.set_trace()
111                           
112        request, response = _SessionMgrService.soap_disconnect(self, ps)
113       
114        # Derive designated user ID differently according to whether
115        # a session ID was passed and the message was signed
116        sessID = request.SessID or None
117               
118        if srv.sm['useSignatureHandler']:
119            # Get certificate corresponding to private key that signed the
120            # message - i.e. the user's proxy
121            userCert = WSSecurityHandler.signatureHandler.verifyingCert
122        else:
123            userCert = request.UserCert
124
125        self.sm.deleteUserSession(sessID=sessID, userCert=userCert)
126        return request, response
127
128
129    def soap_getSessionStatus(self, ps, **kw):
130        '''Check for existence of a session with given session ID or user
131        Distinguished Name
132       
133        @type ps: ZSI ParsedSoap
134        @param ps: client SOAP message
135        @rtype: tuple
136        @return: request and response objects'''
137
138        if self.__debug:
139                import pdb
140                pdb.set_trace()
141               
142        request, response = _SessionMgrService.soap_getSessionStatus(self, ps)
143       
144        response.IsAlive = self.sm.getSessionStatus(userDN=request.UserDN,
145                                                                                            sessID=request.SessID)
146                         
147        return request, response
148
149
150    def soap_getAttCert(self, ps, **kw):
151        '''Get Attribute Certificate from a given Attribute Authority
152        and cache it in user's Credential Wallet
153       
154        @type ps: ZSI ParsedSoap
155        @param ps: client SOAP message
156        @rtype: tuple
157        @return: request and response objects'''
158        if self.__debug:
159                import pdb
160                pdb.set_trace()
161               
162        request, response = _SessionMgrService.soap_getAttCert(self, ps)
163
164        # Get certificate corresponding to private key that signed the
165        # message - i.e. the user's             
166        if srv.sm['useSignatureHandler']:
167            # Get certificate corresponding to private key that signed the
168            # message - i.e. the user's proxy
169            userCert = WSSecurityHandler.signatureHandler.verifyingCert
170        else:
171            userCert = None
172       
173                # Cert used in signature is prefered over userCert input element -
174                # userCert may have been omitted.
175        result = self.sm.getAttCert(\
176                                            userCert=userCert or request.UserCert,
177                                                sessID=request.SessID,
178                                                aaURI=request.AttAuthorityURI,
179                                                reqRole=request.ReqRole,
180                                                mapFromTrustedHosts=request.MapFromTrustedHosts,
181                                                rtnExtAttCertList=request.RtnExtAttCertList,
182                                                extAttCertList=request.ExtAttCert,
183                                                extTrustedHostList=request.ExtTrustedHost)
184
185
186        if result[0]:
187                response.AttCert = result[0].toString() 
188               
189        response.Msg, response.ExtAttCertOut = result[1:]
190       
191        return request, response
192
193
194    def soap_getX509Cert(self, ps, **kw):
195        '''Return Session Manager's X.509 certificate
196       
197        @type ps: ZSI ParsedSoap
198        @param ps: client SOAP message
199        @rtype: tuple
200        @return: request and response objects'''       
201        if self.__debug:
202                import pdb
203                pdb.set_trace()
204               
205        request, response = _SessionMgrService.soap_getX509Cert(self, ps)
206
207        x509Cert = X509CertRead(srv.sm['certFile'])
208        response.X509Cert = base64.encodestring(x509Cert.asDER())
209        return request, response
210
211
212# Create Service
213srv = SessionMgrService()
214
215if srv.sm['useSignatureHandler']:
216        # Initialise WS-Security signature handler passing Session Manager
217        # public and private keys
218   
219    # Inclusive namespaces for Exclusive C14N
220        refC14nKw = {'unsuppressedPrefixes': srv.sm['wssRefInclNS']}
221        signedInfoC14nKw = {'unsuppressedPrefixes':
222                                            srv.sm['wssSignedInfoInclNS']}
223
224        WSSecurityHandler.signatureHandler = SignatureHandler(\
225                                                        verifyingCertFilePath=srv.sm['clntCertFile'],
226                            signingCertFilePath=srv.sm['certFile'],
227                            signingPriKeyFilePath=srv.sm['keyFile'],
228                            signingPriKeyPwd=srv.sm['keyPwd'],
229                            caCertFilePathList=srv.sm.get('caCertFileList'),
230                                        refC14nKw=refC14nKw,
231                                        signedInfoC14nKw=signedInfoC14nKw,
232                                        applySignatureConfirmation=True)
233
234# Add Service to Session Manager branch
235root = Resource()
236root.putChild('SessionManager', srv)
237siteFactory = Site(root)
238
239if srv.sm['useSSL']:
240        # Use SSL connection
241        log.info("Running over https ...")     
242
243        # Using M2Crypto ...
244        import os
245        os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
246
247        import twisted.protocols.policies as policies
248        from M2Crypto import SSL
249        from M2Crypto.SSL import TwistedProtocolWrapper
250        from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
251       
252        siteFactory.startTLS = True
253        siteFactory.sslChecker = SSL.Checker.Checker()
254
255        # TODO: Python ssl client seems to require SSL vers 2 is this a security
256        # risk?
257        ctx = SSL.Context(protocol='sslv23')
258        ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
259        ctx.load_cert(srv.sm['sslCertFile'], 
260                          srv.sm['sslKeyFile'],
261                          callback=lambda *args, **kw: srv.sm['sslKeyPwd'])
262                         
263        ctx.set_allow_unknown_ca(False)
264
265    # TODO: resolve check - verify_peer setting fails with
266    # BIOError: 'no certificate returned' error 18
267#    ctx.set_verify(SSL.verify_peer, 10)
268        ctx.set_verify(SSL.verify_client_once, 1)
269
270        ctx.load_verify_locations(capath=srv.sm['sslCACertDir'])
271
272        class ContextFactory:
273            def getContext(self):
274                return ctx
275       
276        factory = policies.WrappingFactory(siteFactory)
277        factory.protocol.TLS = True
278        factory.protocol = lambda factory, wrappedProtocol: \
279            TLSProtocolWrapper(factory,
280                               wrappedProtocol,
281                               startPassThrough=0,
282                               client=0,
283                               contextFactory=ContextFactory(),
284                               postConnectionCheck=None)
285       
286        siteFactory = factory
287       
288        port = internet.TCPServer(srv.sm['portNum'], siteFactory)
289        port.CERTFILE = srv.sm['sslCertFile']
290        port.KEYFILE = srv.sm['sslKeyFile']
291        root.__class__.server = port
292else:   
293        # Non-SSL
294        log.info("Running over http ...")
295        port = internet.TCPServer(srv.sm['portNum'], siteFactory)
296
297application = service.Application("SessionManagerContainer")
298port.setServiceParent(application)
Note: See TracBrowser for help on using the repository browser.