source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/AttAuthority/server-config.tac @ 2289

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

python/ndg.security.server/ndg/security/server/AttAuthority/server-config.tac:
modified soap_getAttCert to allow for unsigned client messages. If the
useSignatureHandler flag is not set, then the certificate passed in to
AttAuthority?.getAttCert is the userCert element of the SOAP message.

This is a useful capability if both client and service are behind a firewall
and message security is not required.

python/ndg.security.server/ndg/security/server/AttAuthority/init.py,
python/ndg.security.server/ndg/security/server/conf/attAuthorityProperties.
xml,
python/ndg.security.test/ndg/security/test/AttAuthority/siteAAttAuthorityProperties.xml,
python/ndg.security.test/ndg/security/test/AttAuthority/siteBAttAuthorityProperties.xml:
added useSignatureHandler element to list of elements in the properties file.
If this is not set, then the service will not apply signature or signature
verification to messages.

python/ndg.security.test/ndg/security/test/AttAuthority/AttAuthorityClientTest.py: use dictionary get() rather then [key] for signature keywords. This enables
them to be omitted in the config file so as to switch off the signature handler.

python/ndg.security.test/ndg/security/test/AttAuthority/attAuthorityClientTest.cfg: experimented with omitting signature PKI settings.

python/ndg.security.test/ndg/security/test/MyProxy/myProxyProperties.xml:
set serverCNprefix element to host/ for this MyProxy? installations server cert.

python/ndg.security.test/ndg/security/test/MyProxy/myProxyClientTest.cfg:
altered for account on this machine.

python/ndg.security.common/setup.py: slight change to Python 2.5 check for
ElementTree inclusion

python/ndg.security.common/ndg/security/common/AttAuthority/init.py:
SignatureHandler? is now optional. It's left as None if none of the signature
keywords are set via init. It can be set later as the signatureHandler
property now has set capability enabled.

Line 
1#!/usr/bin/env python
2"""NDG Security Attribute Authority .tac file
3
4This file enables the Attribute Authority web service to be
5called under the Twisted framework
6
7NERC Data Grid Project
8
9@author P J Kershaw 17/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 os
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.AttAuthority.AttAuthority_services_server import \
24        AttAuthorityService
25
26from ndg.security.server.AttAuthority import AttAuthority, \
27        AttAuthorityAccessDenied
28       
29from ndg.security.common.wsSecurity import WSSecurityHandlerChainFactory, \
30        WSSecurityHandler, SignatureHandler
31
32from ndg.security.common.X509 import X509Cert, X509CertRead
33
34
35class AttAuthorityServiceSub(AttAuthorityService, WSResource):
36
37    # Add WS-Security handlers
38    factory = WSSecurityHandlerChainFactory
39
40    def __init__(self):
41        WSResource.__init__(self)
42         
43        # Initialize Attribute Authority class - property file will be
44        # picked up from default location under $NDG_DIR directory
45        self.aa = AttAuthority()
46
47
48    def soap_getAttCert(self, ps, **kw):
49        request, response = AttAuthorityService.soap_getAttCert(self, ps)
50       
51        # Derive designated holder cert differently according to whether
52        # a signed message is expected from the client
53        if srv.aa['useSignatureHandler']:
54            # Get certificate corresponding to private key that signed the
55            # message - i.e. the user's proxy
56            holderCert = WSSecurityHandler.signatureHandler.verifyingCert
57        else:
58            # No signature from client - they must instead provide the
59            # designated holder cert via the UserCert input
60            holderCert = request.UserCert
61           
62        try:   
63                attCert = self.aa.getAttCert(userId=request.UserId,
64                                             holderCert=holderCert,
65                                             userAttCert=request.UserAttCert) 
66                response.AttCert = attCert.toString()
67               
68        except AttAuthorityAccessDenied, e:
69            response.Msg = str(e)
70                       
71        return request, response
72
73
74    def soap_getHostInfo(self, ps, **kw):
75        request, response = AttAuthorityService.soap_getHostInfo(self, ps)
76       
77        response.Hostname = srv.aa.hostInfo.keys()[0]
78        response.LoginURI = srv.aa.hostInfo[response.Hostname]['loginURI']
79        response.AaURI = srv.aa.hostInfo[response.Hostname]['aaURI']
80
81        return request, response
82
83
84    def soap_getTrustedHostInfo(self, ps, **kw):
85        request, response = \
86                    AttAuthorityService.soap_getTrustedHostInfo(self, ps)
87       
88        trustedHostInfo = srv.aa.getTrustedHostInfo(role=request.Role)
89
90                # Convert ready for serialization
91        trustedHosts = []
92        for hostname, hostInfo in trustedHostInfo.items():
93            trustedHost = response.new_trustedHosts()
94                       
95            trustedHost.Hostname = hostname
96            trustedHost.AaURI = hostInfo['aaURI']
97            trustedHost.LoginURI = hostInfo['loginURI']
98            trustedHost.RoleList = hostInfo['role']
99                       
100            trustedHosts.append(trustedHost)
101                       
102        response.TrustedHosts = trustedHosts
103               
104        return request, response
105
106
107    def soap_getX509Cert(self, ps, **kw):
108        request, response = AttAuthorityService.soap_getX509Cert(self, ps)
109       
110        x509Cert = X509CertRead(srv.aa['certFile'])
111        response.X509Cert = x509Cert.toString()
112        return request, response
113
114
115root = Resource()
116
117# Create Service
118srv = AttAuthorityServiceSub()
119
120if srv.aa['useSignatureHandler']:
121    # Initialise WS-Security signature handler passing Attribute Authority
122    # public and private keys
123    WSSecurityHandler.signatureHandler = SignatureHandler(\
124                                    verifyingCertFilePath=srv.aa['clntCertFile'],
125                                    signingCertFilePath=srv.aa['certFile'],
126                                    signingPriKeyFilePath=srv.aa['keyFile'],
127                                    signingPriKeyPwd=srv.aa['keyPwd'])
128
129# Add Service to Attribute Authority branch
130root.putChild('AttributeAuthority', srv)
131siteFactory = Site(root)
132
133if srv.aa['useSSL']:
134        # Use SSL connection
135#       from twisted.internet import ssl
136#       
137#       # Nb. ssl.DefaultOpenSSLContextFactory requires pyOpenSSL
138#       ctxFactory = ssl.DefaultOpenSSLContextFactory(srv.aa['sslKeyFile'],
139#                                                                                                 srv.aa['sslCertFile'])
140#       port = internet.SSLServer(srv.aa['portNum'], siteFactory, ctxFactory)
141
142        # Using M2Crypto ...
143    os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
144
145    import twisted.protocols.policies as policies
146    from M2Crypto import SSL
147    from M2Crypto.SSL import TwistedProtocolWrapper
148    from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
149
150    siteFactory.startTLS = True
151    siteFactory.sslChecker = SSL.Checker.Checker()
152
153        # TODO: Python ssl client seems to require SSL vers 2 is this a security
154        # risk?
155    ctx = SSL.Context(protocol='sslv23')
156    ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
157    ctx.load_cert(srv.aa['sslCertFile'], 
158                          srv.aa['sslKeyFile'],
159                          callback=lambda *args, **kw: srv.aa['sslKeyPwd'])
160                         
161    ctx.set_allow_unknown_ca(False)
162    ctx.set_verify(SSL.verify_peer, 10)
163
164    ctx.load_verify_locations(cafile=os.path.basename(srv.aa['caCertFile']), 
165                                                  capath=os.path.dirname(srv.aa['caCertFile']))
166
167    class ContextFactory:
168        def getContext(self):
169            return ctx
170
171    factory = policies.WrappingFactory(siteFactory)
172    factory.protocol.TLS = True
173    factory.protocol = lambda factory, wrappedProtocol: \
174        TLSProtocolWrapper(factory,
175                           wrappedProtocol,
176                           startPassThrough=0,
177                           client=0,
178                           contextFactory=ContextFactory(),
179                           postConnectionCheck=None)
180
181    siteFactory = factory
182   
183    port = internet.TCPServer(srv.aa['portNum'], siteFactory)
184    port.CERTFILE = srv.aa['sslCertFile']
185    port.KEYFILE = srv.aa['sslKeyFile']
186    root.__class__.server = port
187else:   
188        # Non-SSL
189        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
190
191application = service.Application("AttributeAuthorityContainer")
192port.setServiceParent(application)
193       
Note: See TracBrowser for help on using the repository browser.