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.

RevLine 
[1724]1#!/usr/bin/env python
[2136]2"""NDG Security Session Manager .tac file
[1724]3
[1747]4This file enables the Session Manager web service to be
[1724]5called under the Twisted framework
6
7NERC Data Grid Project
8
[2058]9@author P J Kershaw 23/11/06
[1724]10
[2058]11@copyright (C) 2007 CCLRC & NERC
[1724]12
[2058]13@license This software may be distributed under the terms of the Q Public
14License, version 1.0 or later.
[1724]15"""
[2530]16import base64
17
[1714]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
[2730]23from ndg.security.server.SessionMgr.SessionMgr_services_server import \
24        SessionMgrService
[1773]25from ndg.security.server.SessionMgr import SessionMgr
[2855]26from ndg.security.common.wsSecurity import SignatureHandler
27from ndg.security.server.twisted import WSSecurityHandler, \
28        WSSecurityHandlerChainFactory
29       
30
[2620]31from ndg.security.common.X509 import X509CertRead
[1730]32
[1777]33
[1747]34class SessionMgrServiceSub(SessionMgrService, WSResource):
[1785]35
36    # Add WS-Security handlers
37    factory = WSSecurityHandlerChainFactory
38       
[1784]39    def __init__(self):
[2418]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) 
[2058]49        self.sm = SessionMgr()
[2418]50
51
52    def soap_addUser(self, ps, **kw):
53        '''Add a new user account
[1784]54       
[2418]55        @type ps: ZSI ParsedSoap
56        @param ps: client SOAP message
57        @rtype: tuple
58        @return: request and response objects'''
59
[1784]60        request, response = SessionMgrService.soap_addUser(self, ps)
61        return request, response
[1714]62
[2418]63
[1784]64    def soap_connect(self, ps, **kw):
[2418]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
[1784]72        request, response = SessionMgrService.soap_connect(self, ps)
[2620]73       
[2079]74        result = self.sm.connect(username=request.Username,
75                                                                 passphrase=request.Passphrase,
[2620]76                                                                 createServerSess=request.CreateServerSess)
[2063]77                                       
[2079]78        response.ProxyCert, response.ProxyPriKey, response.UserCert, \
[2620]79                response.SessID = result
[1783]80                         
[1784]81        return request, response
[1724]82
[2418]83
[1784]84    def soap_disconnect(self, ps, **kw):
[2418]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'''
[2437]91           
[1784]92        request, response = SessionMgrService.soap_disconnect(self, ps)
[2437]93       
94        # Derive designated user ID differently according to whether
95        # a session ID was passed and the message was signed
[2620]96        sessID = request.SessID or None
[2437]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:
[2620]103            userCert = request.UserCert
[2530]104
105        self.sm.deleteUserSession(sessID=sessID, proxyCert=userCert)
[1784]106        return request, response
[1724]107
[2418]108
[2058]109    def soap_getAttCert(self, ps, **kw):
[2418]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
[2058]118        request, response = SessionMgrService.soap_getAttCert(self, ps)
[2620]119
[2076]120        # Get certificate corresponding to private key that signed the
[2437]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
[2076]128       
[2418]129                # Cert used in signature is prefered over userCert input element -
130                # userCert may have been omitted.
[2079]131        result = self.sm.getAttCert(\
[2418]132                                            userCert=userCert or request.UserCert,
[2079]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)
[2076]140
141
[2085]142        if result[0]:
143                response.AttCert = result[0].toString() 
144               
[2108]145        response.Msg, response.ExtAttCertOut = result[1:]
[2076]146       
[1784]147        return request, response
[1747]148
[2418]149
[1784]150    def soap_getX509Cert(self, ps, **kw):
[2418]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       
[1784]158        request, response = SessionMgrService.soap_getX509Cert(self, ps)
[2530]159
160        x509Cert = X509CertRead(srv.sm['certFile'])
161        response.X509Cert = base64.encodestring(x509Cert.asDER())
[1784]162        return request, response
[1724]163
[1714]164
[2058]165# Create Service
[2136]166srv = SessionMgrServiceSub()
[2058]167
[2530]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(\
[2136]180                                                                verifyingCertFilePath=srv.sm['clntCertFile'],
181                                    signingCertFilePath=srv.sm['certFile'],
182                                    signingPriKeyFilePath=srv.sm['keyFile'],
[2530]183                                    signingPriKeyPwd=srv.sm['keyPwd'],
184                                    caCertFilePathList=caCertFilePathList)
[2058]185
186# Add Service to Session Manager branch
[1714]187root = Resource()
[2136]188root.putChild('SessionManager', srv)
[1714]189siteFactory = Site(root)
[1778]190
[2136]191if srv.sm['useSSL']:
[2063]192        # Use SSL connection
[2418]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
[2063]208       
[2418]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
[2063]250else:   
251        # Non-SSL
[2136]252        port = internet.TCPServer(srv.sm['portNum'], siteFactory)
[1785]253
[2136]254application = service.Application("SessionManagerContainer")
[1783]255port.setServiceParent(application)
Note: See TracBrowser for help on using the repository browser.