source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/conf/attAuthority.tac @ 4110

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

Allow BinarySecurityToken? ValueType? and whether SignatureConfirmation?
is required to be set from server xml properties file.

RevLine 
[2866]1"""NDG Security Attribute Authority .tac file
2
3This file enables the Attribute Authority web service to be
4called under the Twisted framework
5
6NERC Data Grid Project
[2948]7"""
8__author__ = "P J Kershaw"
9__date__ = "17/11/06"
10__copyright__ = "(C) 2007 STFC & NERC"
11__license__ = \
12"""This software may be distributed under the terms of the Q Public
13License, version 1.0 or later."""
14__contact__ = "P.J.Kershaw@rl.ac.uk"
15__revision__ = '$Id$'
[2866]16
17import os, base64
[2899]18from logging.config import fileConfig
19try:
20        _logConfig = os.path.join(os.environ["NDGSEC_DIR"],
21                                                          'conf',
22                                                          'attAuthorityLog.cfg')
[2948]23        fileConfig(_logConfig)
[2899]24except KeyError:
25        from warnings import warn
26        warn(\
27        '"NDGSEC_DIR" environment variable must be set to enable logging config',
28        RuntimeWarning)
29       
30import logging
31log = logging.getLogger(__name__)
[2866]32
33from ZSI.twisted.WSresource import WSResource
34from twisted.application import service, internet
35from twisted.web.server import Site
36from twisted.web.resource import Resource
37
38from ndg.security.server.AttAuthority.AttAuthority_services_server import \
39        AttAuthorityService
40
41from ndg.security.server.AttAuthority import AttAuthority, \
42        AttAuthorityAccessDenied
43       
44from ndg.security.common.wsSecurity import SignatureHandler
45from ndg.security.server.twisted import WSSecurityHandlerChainFactory, \
46        WSSecurityHandler
47
48from ndg.security.common.X509 import X509Cert, X509CertRead
49
50
51class AttAuthorityServiceSub(AttAuthorityService, WSResource):
52
53    # Add WS-Security handlers
54    factory = WSSecurityHandlerChainFactory
55
56    def __init__(self):
[2948]57       
58        # Stop in debugger at beginning of SOAP stub if environment variable
59        # is set
60        self.__debug = bool(os.environ.get('NDGSEC_INT_DEBUG'))
61        if self.__debug:
62                import pdb
63                pdb.set_trace()
64               
[2866]65        WSResource.__init__(self)
66         
67        # Initialize Attribute Authority class - property file will be
68        # picked up from default location under $NDG_DIR directory
69        self.aa = AttAuthority()
70
71
72    def soap_getAttCert(self, ps, **kw):
[2884]73        '''Retrieve an Attribute Certificate
74       
75        @type ps: ZSI ParsedSoap
76        @param ps: client SOAP message
77        @rtype: tuple
78        @return: request and response objects'''
79        if self.__debug:
80                import pdb
81                pdb.set_trace()
82               
[2866]83        request, response = AttAuthorityService.soap_getAttCert(self, ps)
84
85        # Derive designated holder cert differently according to whether
86        # a signed message is expected from the client
87        if srv.aa['useSignatureHandler']:
88            # Get certificate corresponding to private key that signed the
89            # message - i.e. the user's proxy
90            holderCert = WSSecurityHandler.signatureHandler.verifyingCert
91        else:
92            # No signature from client - they must instead provide the
93            # designated holder cert via the UserCert input
94            holderCert = request.UserCert
95
96        try:   
97                attCert = self.aa.getAttCert(userId=request.UserId,
98                                         holderCert=holderCert,
99                                         userAttCert=request.UserAttCert) 
100                response.AttCert = attCert.toString()
101               
102        except AttAuthorityAccessDenied, e:
103            response.Msg = str(e)
104                       
105        return request, response
[2931]106       
[2866]107
108    def soap_getHostInfo(self, ps, **kw):
[2884]109        '''Get information about this host
110               
111        @type ps: ZSI ParsedSoap
112        @param ps: client SOAP message
113        @rtype: tuple
114        @return: request and response objects'''
115        if self.__debug:
116                import pdb
117                pdb.set_trace()
118               
[2866]119        request, response = AttAuthorityService.soap_getHostInfo(self, ps)
120       
121        response.Hostname = srv.aa.hostInfo.keys()[0]
[2931]122        response.AaURI = srv.aa.hostInfo[response.Hostname]['aaURI']
123        response.AaDN = srv.aa.hostInfo[response.Hostname]['aaDN']
[2866]124        response.LoginURI = srv.aa.hostInfo[response.Hostname]['loginURI']
[2931]125        response.LoginServerDN = \
126                srv.aa.hostInfo[response.Hostname]['loginServerDN']
127        response.LoginRequestServerDN = \
128                srv.aa.hostInfo[response.Hostname]['loginRequestServerDN']
[2866]129
130        return request, response
[2931]131       
[2866]132
[2931]133    def soap_getAllHostsInfo(self, ps, **kw):
134        '''Get information about all hosts
135               
136        @type ps: ZSI ParsedSoap
137        @param ps: client SOAP message
138        @rtype: tuple
139        @return: request and response objects'''
140        if self.__debug:
141                import pdb
142                pdb.set_trace()
143               
144        request, response = AttAuthorityService.soap_getAllHostsInfo(self, ps)
145       
[2866]146
[2931]147        trustedHostInfo = srv.aa.getTrustedHostInfo()
148
149                # Convert ready for serialization
150               
151                # First get info for THIS Attribute Authority ...
152                # Nb. No role lsit applies here
153        hosts = [response.new_hosts()]
154       
155        hosts[0].Hostname = srv.aa.hostInfo.keys()[0]
156       
157        hosts[0].AaURI = \
158                srv.aa.hostInfo[hosts[0].Hostname]['aaURI']
159        hosts[0].AaDN = \
160                srv.aa.hostInfo[hosts[0].Hostname]['aaDN']
161
162        hosts[0].LoginURI = srv.aa.hostInfo[hosts[0].Hostname]['loginURI']
163        hosts[0].LoginServerDN = \
164                srv.aa.hostInfo[hosts[0].Hostname]['loginServerDN']
165        hosts[0].LoginRequestServerDN = \
166                srv.aa.hostInfo[hosts[0].Hostname]['loginRequestServerDN']
167       
168                # ... then append info for other trusted attribute authorities...
169        for hostname, hostInfo in trustedHostInfo.items():
170            host = response.new_hosts()
171                       
172            host.Hostname = hostname
173            host.AaURI = hostInfo['aaURI']
174            host.AaDN = hostInfo['aaDN']
175            host.LoginURI = hostInfo['loginURI']
176            host.LoginServerDN = hostInfo['loginServerDN']
177            host.LoginRequestServerDN=hostInfo['loginRequestServerDN']
178            host.RoleList = hostInfo['role']
179                       
180            hosts.append(host)
181                       
182        response.Hosts = hosts
183
184        return request, response
185
186
[2866]187    def soap_getTrustedHostInfo(self, ps, **kw):
[2884]188        '''Get information about other trusted hosts
189               
190        @type ps: ZSI ParsedSoap
191        @param ps: client SOAP message
192        @rtype: tuple
193        @return: request and response objects'''
194        if self.__debug:
195                import pdb
196                pdb.set_trace()
197               
[2866]198        request, response = \
199                        AttAuthorityService.soap_getTrustedHostInfo(self, ps)
200       
201        trustedHostInfo = srv.aa.getTrustedHostInfo(role=request.Role)
202
203                # Convert ready for serialization
204        trustedHosts = []
205        for hostname, hostInfo in trustedHostInfo.items():
206            trustedHost = response.new_trustedHosts()
207                       
208            trustedHost.Hostname = hostname
209            trustedHost.AaURI = hostInfo['aaURI']
[2931]210            trustedHost.AaDN = hostInfo['aaDN']
[2866]211            trustedHost.LoginURI = hostInfo['loginURI']
[2931]212            trustedHost.LoginServerDN = hostInfo['loginServerDN']
213            trustedHost.LoginRequestServerDN=hostInfo['loginRequestServerDN']
[3040]214            trustedHost.RoleList = hostInfo['role']
[2866]215                       
216            trustedHosts.append(trustedHost)
217                       
218        response.TrustedHosts = trustedHosts
219               
220        return request, response
221
222
223    def soap_getX509Cert(self, ps, **kw):
[2884]224        '''Retrieve Attribute Authority's X.509 certificate
225       
226        @type ps: ZSI ParsedSoap
227        @param ps: client SOAP message
228        @rtype: tuple
229        @return: request and response objects'''
230        if self.__debug:
231                import pdb
232                pdb.set_trace()
233               
[2866]234        request, response = AttAuthorityService.soap_getX509Cert(self, ps)
235       
236        x509Cert = X509CertRead(srv.aa['certFile'])
237        response.X509Cert = base64.encodestring(x509Cert.asDER())
238        return request, response
239
240
241root = Resource()
242
243# Create Service
244srv = AttAuthorityServiceSub()
245if srv.aa['useSignatureHandler']:
246    # Initialise WS-Security signature handler passing Attribute Authority
247    # public and private keys
[3652]248   
249    # Inclusive namespaces for Exclusive C14N
250    refC14nKw = {'unsuppressedPrefixes': srv.aa['wssRefInclNS']}
251    signedInfoC14nKw = {'unsuppressedPrefixes':
252                        srv.aa['wssSignedInfoInclNS']}
253   
[2866]254    WSSecurityHandler.signatureHandler = SignatureHandler(\
[3652]255                                        verifyingCertFilePath=srv.aa['clntCertFile'],
256                                        signingCertFilePath=srv.aa['certFile'],
257                                        signingPriKeyFilePath=srv.aa['keyFile'],
258                                        signingPriKeyPwd=srv.aa['keyPwd'],
259                                        caCertFilePathList=srv.aa.get('caCertFileList'),
260                                        refC14nKw=refC14nKw,
[4110]261                                        signedInfoC14nKw=signedInfoC14nKw,
262                                        reqBinSecTokValType=srv.aa.get('reqBinSecTokValType'),
263                                        applySignatureConfirmation=srv.aa.get('applySignatureConfirmation'))
[2866]264
265# Add Service to Attribute Authority branch
266root.putChild('AttributeAuthority', srv)
267siteFactory = Site(root)
268if srv.aa['useSSL']:
[2899]269        log.info("Running over https ...")
[2866]270
[2899]271        os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
[2866]272
[2899]273        import twisted.protocols.policies as policies
[2866]274
[2899]275        # Using M2Crypto
276        from M2Crypto import SSL
277        from M2Crypto.SSL import TwistedProtocolWrapper
278        from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
[2866]279
[2899]280        siteFactory.startTLS = True
281        siteFactory.sslChecker = SSL.Checker.Checker()
282       
[2866]283        # TODO: Python ssl client seems to require SSL vers 2 is this a security
284        # risk?
[2899]285        ctx = SSL.Context(protocol='sslv23')
286        ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
287        ctx.load_cert(srv.aa['sslCertFile'],
288                                  srv.aa['sslKeyFile'],
289                                  callback=lambda *args, **kw: srv.aa['sslKeyPwd'])
290                                 
291        ctx.set_allow_unknown_ca(False)
292       
293        # TODO: resolve check - verify_peer setting fails with
294        # BIOError: 'no certificate returned' error 18
295        #    ctx.set_verify(SSL.verify_peer, 10)
296        ctx.set_verify(SSL.verify_client_once, 1)
297       
[3135]298        ctx.load_verify_locations(capath=srv.aa['sslCACertDir'])
[2899]299       
300        class ContextFactory:
301            def getContext(self):
302                return ctx
303       
304        factory = policies.WrappingFactory(siteFactory)
305        factory.protocol.TLS = True
306        factory.protocol = lambda factory, wrappedProtocol: \
307            TLSProtocolWrapper(factory,
308                               wrappedProtocol,
309                               startPassThrough=0,
310                               client=0,
311                               contextFactory=ContextFactory(),
312                               postConnectionCheck=None)
313       
314        siteFactory = factory
315       
316        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
317        port.CERTFILE = srv.aa['sslCertFile']
318        port.KEYFILE = srv.aa['sslKeyFile']
319        root.__class__.server = port
[2866]320else:   
321        # Non-SSL
[2899]322        log.info("Running over http ...")       
[2866]323        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
324
325application = service.Application("AttributeAuthorityContainer")
326port.setServiceParent(application)
327       
Note: See TracBrowser for help on using the repository browser.