source: TI12-security/trunk/python/ndg.security.common/ndg/security/common/m2CryptoSSLUtility.py @ 2902

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.common/ndg/security/common/m2CryptoSSLUtility.py@2902
Revision 2902, 6.7 KB checked in by pjkersha, 13 years ago (diff)

Added logging to major modules

ndg.security.server/ndg/security/server/AttAuthority/init.py:

  • Parent exception class AttAuthorityError? now also writes to ERROR log when raised.
  • Logging info added
  • ACs issued are now logged using a RotatingFileHandler? to enable prevention of disk overflow
  • AC log rotating file handler can be configured via the properties file to set the max number of AC files

ndg.security.server/ndg/security/server/conf/sessionMgrLog.cfg,
ndg.security.server/ndg/security/server/conf/attAuthorityLog.cfg:

  • increased max log file size for rotation

ndg.security.server/ndg/security/server/SessionMgr/init.py:

  • Parent exception class _SessionMgrException now also writes to ERROR log when raised.
  • Logging info added

ndg.security.test/ndg/security/test/SessionMgr/sessionMgrClientTest.cfg:

  • modified settings for testing

ndg.security.common/ndg/security/common/SessionMgr/init.py,
ndg.security.common/ndg/security/common/AttAuthority/init.py:

  • added getURI method to enable read access to uri attribute

ndg.security.common/ndg/security/common/m2CryptoSSLUtility.py:

  • Reset default timeout to 20s. 3s timeout caused intermittent errors in tests.

ndg.security.common/ndg/security/common/CredWallet.py:

  • adding logging calls.
  • Parent exception class _CredWalletException now also writes to ERROR log when raised.
  • Removed CredWallet?.str - not needed
Line 
1import httplib
2import socket
3
4from M2Crypto import SSL, X509
5from M2Crypto.httpslib import HTTPSConnection as _HTTPSConnection
6
7from ndg.security.common.X509 import X509Cert, X509Stack
8
9class InvalidCertSignature(SSL.Checker.SSLVerificationError):
10    """Raise if verification against CA cert public key fails"""
11   
12
13class HostCheck(SSL.Checker.Checker, object):
14    """Override SSL.Checker.Checker to enable alternate Common Name
15    setting match for peer cert"""
16
17    def __init__(self, 
18                 peerCertDN=None, 
19                 peerCertCN=None, 
20                 caCertList=[],
21                 caCertFilePathList=[], 
22                 **kw):
23        """Override parent class __init__ to enable setting of myProxyServerDN
24        setting
25       
26        @type peerCertDN: string
27        @keyword peerCertDN: Set the expected Distinguished Name of the
28        server to avoid errors matching hostnames.  This is useful
29        where the hostname is not fully qualified
30       
31        @type peerCertCN: string
32        @keyword peerCertCN: enable alternate Common Name to peer
33        hostname
34       
35        @type caCertList: list type of M2Crypto.X509.X509 types
36        @keyword caCertList: CA X.509 certificates - if set the peer cert's
37        CA signature is verified against one of these.  At least one must
38        verify
39       
40        @type caCertFilePathList: list string types
41        @keyword caCertFilePathList: same as caCertList except input as list
42        of CA cert file paths"""
43       
44        SSL.Checker.Checker.__init__(self, **kw)
45       
46        self.peerCertDN = peerCertDN
47        self.peerCertCN = peerCertCN
48        if caCertList:
49            self.caCertList = caCertList
50        elif caCertFilePathList:
51            self.caCertFilePathList = caCertFilePathList
52           
53       
54    def __call__(self, peerCert, host=None):
55        """Carry out checks on server ID
56        @param peerCert: MyProxy server host certificate as M2Crypto.X509.X509
57        instance
58        @keyword host: name of host to check
59        """
60       
61        try:
62            SSL.Checker.Checker.__call__(self, peerCert, host=self.peerCertCN)
63           
64        except SSL.Checker.WrongHost, e:
65            # Try match against peerCertDN set
66            # file setting
67            peerCertDN='/'+peerCert.get_subject().as_text().replace(', ', '/')
68            if peerCertDN != self.peerCertDN:
69                raise e
70
71        if len(self.__caCertStack) > 0:
72            try:
73                self.__caCertStack.verifyCertChain(\
74                           x509Cert2Verify=X509Cert(m2CryptoX509=peerCert))
75            except Exception, e:
76                raise InvalidCertSignature, \
77            "Peer certificate verification against CA cert failed: "+str(e) 
78             
79        # They match - drop the exception and return all OK instead         
80        return True
81   
82   
83    def __setCACertList(self, caCertList):
84        """Set list of CA certs - peer cert must validate against at least one
85        of these"""
86        self.__caCertStack = X509Stack()
87        for caCert in caCertList:
88            self.__caCertStack.push(caCert)
89
90    caCertList = property(fset=__setCACertList,
91              doc="list of CA certs - peer cert must validate against one")
92
93
94    #_________________________________________________________________________
95    def __setCACertsFromFileList(self, caCertFilePathList):
96        '''Read CA certificates from file and add them to the X.509
97        stack
98       
99        @type caCertFilePathList: list or tuple
100        @param caCertFilePathList: list of file paths for CA certificates to
101        be used to verify certificate used to sign message'''
102       
103        if not isinstance(caCertFilePathList, list) and \
104           not isinstance(caCertFilePathList, tuple):
105            raise AttributeError, \
106                        'Expecting a list or tuple for "caCertFilePathList"'
107
108        self.__caCertStack = X509Stack()
109
110        for caCertFilePath in caCertFilePathList:
111            self.__caCertStack.push(X509.load_cert(caCertFilePath))
112       
113    caCertFilePathList = property(fset=__setCACertsFromFileList,
114    doc="list of CA cert file paths - peer cert must validate against one")
115
116
117class HTTPSConnection(_HTTPSConnection):
118    """Modified version of M2Crypto equivalent to enable custom checks with
119    the peer and timeout settings
120   
121    @type defReadTimeout: M2Crypto.SSL.timeout
122    @cvar defReadTimeout: default timeout for read operations
123    @type defWriteTimeout: M2Crypto.SSL.timeout
124    @cvar defWriteTimeout: default timeout for write operations"""   
125    defReadTimeout = SSL.timeout(sec=20.)
126    defWriteTimeout = SSL.timeout(sec=20.)
127   
128    def __init__(self, *args, **kw):
129        '''Overload to enable setting of post connection check
130        callback to SSL.Connection
131       
132        type *args: tuple
133        param *args: args which apply to M2Crypto.httpslib.HTTPSConnection
134        type **kw: dict
135        param **kw: additional keywords - postConnectionCheck - set class for
136        checking peer, readTimeout - M2Crypto.SSL.timeout instance - set
137        timeout for read, similarly writeTimeout'''
138       
139        if 'postConnectionCheck' in kw:
140            self._postConnectionCheck = kw['postConnectionCheck']
141            del kw['postConnectionCheck']
142        else:
143            self._postConnectionCheck = SSL.Checker.Checker
144       
145        if 'readTimeout' in kw:
146            if not isinstance(readTimeout, SSL.timeout):
147                raise AttributeError, "readTimeout must be of type " + \
148                                      "M2Crypto.SSL.timeout" 
149            self.readTimeout = readTimeout
150            del kw['readTimeout']
151        else:
152            self.readTimeout = HTTPSConnection.defReadTimeout
153             
154        if 'writeTimeout' in kw:
155            if not isinstance(writeTimeout, SSL.timeout):
156                raise AttributeError, "writeTimeout must be of type " + \
157                                      "M2Crypto.SSL.timeout" 
158            self.writeTimeout = writeTimeout
159            del kw['writeTimeout']
160        else:
161            self.writeTimeout = HTTPSConnection.defWriteTimeout
162           
163        _HTTPSConnection.__init__(self, *args, **kw)
164       
165       
166    def connect(self):
167        '''Overload M2Crypto.httpslib.HTTPSConnection to enable
168        custom post connection check of peer certificate and socket timeout'''
169        self.sock = SSL.Connection(self.ssl_ctx)
170        self.sock.set_post_connection_check_callback(
171                                                 self._postConnectionCheck)
172
173        self.sock.set_socket_read_timeout(self.readTimeout)
174        self.sock.set_socket_write_timeout(self.writeTimeout)
175
176        self.sock.connect((self.host, self.port))
Note: See TracBrowser for help on using the repository browser.