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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/SessionMgr/server-config.tac@2855
Revision 2855, 8.3 KB checked in by pjkersha, 12 years ago (diff)

Fixes to tickets #828 #829

ndg.security.server/ndg/security/server/AttAuthority/server-config.tac,
ndg.security.server/ndg/security/server/ca/server-config.tac,
ndg.security.server/ndg/security/server/SessionMgr/server-config.tac:

  • Split import for wsSecurity into common component (no Zope or Twisted) and

server component (Zope and Twisted imports)

ndg.security.server/ndg/security/server/twisted.py:

  • new module to contain Twisted handler code for NDG-Security server egg.

This code is removed from common.wsSecurity so that the client egg no longer
has any Twisted or Zope dependencies

ndg.security.common/ndg/security/common/wsSecurity.py: removed Twisted handler
code and moved to new server.twisted module

ndg-security-install.py: add new --config-dir option to copy server egg conf/
dir contents to /etc/ndg/security on target host. Incomplete as a way to
programmatically get the egg site-packages/ location is needed.

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