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

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

General refactoring and updating of code, including:

Removal of refC14nKw and singnedInfoC14nKw keywords in wsssecurity session manager config
(the refC14nInclNS and signedInfoC14nInclNS keywords are sufficient);
Creation of new DOM signature handler class, dom.py, based on the wsSecurity
class;
Abstraction of common code between dom.py and etree.py into new parent
class, BaseSignatureHandler?.py.
Fixing and extending use of properties in the SignatureHandler? code.
Fixing a few bugs with the original SignatureHandler? code.
Updating of test cases to new code/code structure.

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 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.dom 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):
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               
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):
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               
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
106       
107
108    def soap_getHostInfo(self, ps, **kw):
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               
119        request, response = AttAuthorityService.soap_getHostInfo(self, ps)
120       
121        response.Hostname = srv.aa.hostInfo.keys()[0]
122        response.AaURI = srv.aa.hostInfo[response.Hostname]['aaURI']
123        response.AaDN = srv.aa.hostInfo[response.Hostname]['aaDN']
124        response.LoginURI = srv.aa.hostInfo[response.Hostname]['loginURI']
125        response.LoginServerDN = \
126                srv.aa.hostInfo[response.Hostname]['loginServerDN']
127        response.LoginRequestServerDN = \
128                srv.aa.hostInfo[response.Hostname]['loginRequestServerDN']
129
130        return request, response
131       
132
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       
146
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
187    def soap_getTrustedHostInfo(self, ps, **kw):
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               
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']
210            trustedHost.AaDN = hostInfo['aaDN']
211            trustedHost.LoginURI = hostInfo['loginURI']
212            trustedHost.LoginServerDN = hostInfo['loginServerDN']
213            trustedHost.LoginRequestServerDN=hostInfo['loginRequestServerDN']
214            trustedHost.RoleList = hostInfo['role']
215                       
216            trustedHosts.append(trustedHost)
217                       
218        response.TrustedHosts = trustedHosts
219               
220        return request, response
221
222
223    def soap_getX509Cert(self, ps, **kw):
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               
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
248   
249    # Inclusive namespaces for Exclusive C14N
250    refC14nInclNS = srv.aa['wssRefInclNS']
251    signedInfoC14nInclNS = srv.aa['wssSignedInfoInclNS']
252   
253    WSSecurityHandler.signatureHandler = SignatureHandler(\
254                                        verifyingCertFilePath=srv.aa['clntCertFile'],
255                                        signingCertFilePath=srv.aa['certFile'],
256                                        signingPriKeyFilePath=srv.aa['keyFile'],
257                                        signingPriKeyPwd=srv.aa['keyPwd'],
258                                        caCertFilePathList=srv.aa.get('caCertFileList'),
259                                        refC14nInclNS=refC14nInclNS,
260                                        signedInfoC14nInclNS=signedInfoC14nInclNS,
261                                        reqBinSecTokValType=srv.aa.get('reqBinSecTokValType'),
262                                        applySignatureConfirmation=srv.aa.get('applySignatureConfirmation'))
263
264# Add Service to Attribute Authority branch
265root.putChild('AttributeAuthority', srv)
266siteFactory = Site(root)
267if srv.aa['useSSL']:
268        log.info("Running over https ...")
269
270        os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
271
272        import twisted.protocols.policies as policies
273
274        # Using M2Crypto
275        from M2Crypto import SSL
276        from M2Crypto.SSL import TwistedProtocolWrapper
277        from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
278
279        siteFactory.startTLS = True
280        siteFactory.sslChecker = SSL.Checker.Checker()
281       
282        # TODO: Python ssl client seems to require SSL vers 2 is this a security
283        # risk?
284        ctx = SSL.Context(protocol='sslv23')
285        ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
286        ctx.load_cert(srv.aa['sslCertFile'],
287                                  srv.aa['sslKeyFile'],
288                                  callback=lambda *args, **kw: srv.aa['sslKeyPwd'])
289                                 
290        ctx.set_allow_unknown_ca(False)
291       
292        # TODO: resolve check - verify_peer setting fails with
293        # BIOError: 'no certificate returned' error 18
294        #    ctx.set_verify(SSL.verify_peer, 10)
295        ctx.set_verify(SSL.verify_client_once, 1)
296       
297        ctx.load_verify_locations(capath=srv.aa['sslCACertDir'])
298       
299        class ContextFactory:
300            def getContext(self):
301                return ctx
302       
303        factory = policies.WrappingFactory(siteFactory)
304        factory.protocol.TLS = True
305        factory.protocol = lambda factory, wrappedProtocol: \
306            TLSProtocolWrapper(factory,
307                               wrappedProtocol,
308                               startPassThrough=0,
309                               client=0,
310                               contextFactory=ContextFactory(),
311                               postConnectionCheck=None)
312       
313        siteFactory = factory
314       
315        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
316        port.CERTFILE = srv.aa['sslCertFile']
317        port.KEYFILE = srv.aa['sslKeyFile']
318        root.__class__.server = port
319else:   
320        # Non-SSL
321        log.info("Running over http ...")       
322        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
323
324application = service.Application("AttributeAuthorityContainer")
325port.setServiceParent(application)
326       
Note: See TracBrowser for help on using the repository browser.