source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/twisted/attributeauthority/attAuthority.tac @ 4392

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/zsi/twisted/attributeauthority/attAuthority.tac@4392
Revision 4392, 10.8 KB checked in by pjkersha, 11 years ago (diff)

Rerun Credential Wallet and AA client unittests with refactored WSDL stubs in place.

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