Changeset 2150
- Timestamp:
- 13/02/07 09:56:51 (14 years ago)
- Location:
- TI12-security/trunk/python
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/python/ndg.security.common/ndg/security/common/openssl.py
r2148 r2150 14 14 15 15 import re, os 16 from ConfigParser import SafeConfigParser 16 17 17 18 #_____________________________________________________________________________ … … 21 22 22 23 #_____________________________________________________________________________ 23 class OpenSSLConfig( object):24 class OpenSSLConfig(SafeConfigParser, object): 24 25 """Wrapper to OpenSSL Configuration file to allow extraction of 25 26 required distinguished name used for making certificate requests 26 27 27 @cvar __reqDnRE: regular expression pattern for locating required 28 distinguished name from the config file 29 28 @type _certReqDNParamName: tuple 30 29 @cvar _certReqDNParamName: permissable keys for Distinguished Name 31 30 (not including CN which gets set separately). This is used in __setReqDN 32 to check input""" 33 34 __reqDnRE = '\[\s*req_distinguished_name\s*\].*\[' 35 31 to check input 32 33 @type _caDirPat: string 34 @cvar _caDirPat: sub-directory path to CA config directory 35 @type __gridCASubDir: string 36 @cvar __gridCASubDir: sub-directory of globus user for CA settings""" 37 36 38 _certReqDNParamName = ('O', 'OU', '0.organizationName', 37 39 '0.organizationalUnitName') 40 41 _caDirPat = re.compile('\$dir') 42 43 __gridCASubDir = os.path.join(".globus", "simpleCA") 38 44 39 45 … … 44 50 @param filePath: path to OpenSSL configuration file""" 45 51 46 # Content of file47 self.__fileTxt = None52 SafeConfigParser.__init__(self) 53 48 54 self.__reqDN = None 49 55 self.__setFilePath(filePath) 56 57 # Set-up CA directory 58 if not os.environ.get('HOME'): 59 raise SimpleCAError, "Environment variable \"HOME\" is not set" 60 61 self.__caDir = os.path.join(os.environ['HOME'], self.__gridCASubDir) 50 62 51 63 … … 79 91 fset=__setFilePath, 80 92 doc="file path for configuration file") 81 82 def __getFileTxt(self): 83 """Get content of file in call to getReqDN 84 @rtype: string 85 @return: content of file""" 86 return self.__fileTxt 87 88 def __setFileTxt(self, input): 89 """Set content of file 90 @type input: string 91 @param input: content of file.""" 92 if input is not None and not isinstance(input, basestring): 93 raise AttributeError, "File text must be string or None type" 94 95 self.__fileTxt = input 96 97 98 fileTxt = property(fset=__setFileTxt, 99 fget=__getFileTxt, 100 doc="Content of SSL file") 93 94 95 def __setCADir(self, caDir): 96 """Set property method 97 @param caDir: path for OpenSSL configuration file""" 98 if filePath is not None: 99 if not isinstance(caDir, basestring): 100 raise OpenSSLConfigError, \ 101 "Input OpenSSL CA directory path must be a string" 102 103 try: 104 if not os.access(caDir, os.R_OK): 105 raise OpenSSLConfigError, "not found or no read access" 106 107 except Exception, e: 108 raise OpenSSLConfigError, \ 109 "OpenSSL CA directory path is not valid: \"%s\": %s" % \ 110 (filePath, str(e)) 111 112 self.__caDir = caDir 113 114 115 def __getCADir(self): 116 """Get property method 117 @type caDir: string 118 @return caDir: directory path for CA configuration files""" 119 return self.__caDir 120 121 caDir = property(fget=__getCADir, 122 fset=__setCADir, 123 doc="directory path for CA configuration files") 101 124 102 125 … … 106 129 @return reqDN: Distinguished Name for certificate request""" 107 130 return self.__reqDN 131 108 132 109 133 def __setReqDN(self, reqDN): … … 128 152 doc="Distinguished Name for certificate request") 129 153 130 131 154 def read(self): 132 """Read OpenSSL configuration file and parse certificate request 133 Distinguished Name settings""" 134 155 """Override base class version to avoid parsing error with the first 156 'RANDFILE = ...' part of the openssl file. Also, reformat _sections 157 to allow for the style of SSL config files where section headings can 158 have spaces either side of the brackets e.g. 159 [ sectionName ] 160 161 and comments can occur on the same line as an option e.g. 162 option = blah # This is option blah 163 164 Reformat _sections to """ 135 165 try: 136 self.__fileTxt = open(self.__filePath).read() 166 file = open(self.__filePath) 167 fileTxt = file.read() 137 168 except Exception, e: 138 169 raise OpenSSLConfigError, \ 139 170 "Error reading OpenSSL config file \"%s\": %s" % \ 140 171 (self.__filePath, str(e)) 172 173 idx = re.search('\[\s*\w*\s*\]', fileTxt).span()[0] 174 file.seek(idx) 175 SafeConfigParser.readfp(self, file) 176 177 # Filter section names and reomve comments from options 178 for section, val in self._sections.items(): 179 newSection = section 180 self._sections[newSection.strip()] = \ 181 dict([(opt, self._filtOptVal(optVal)) 182 for opt, optVal in val.items()]) 183 del self._sections[section] 184 185 self._setReqDN() 186 187 188 def _filtOptVal(self, optVal): 189 """For option value, filter out comments and substitute $dir with 190 the CA directory location""" 191 return self.__class__._caDirPat.sub(self.__caDir, 192 optVal.split('#')[0].strip()) 193 194 195 def readfp(self, fp): 196 """Set to not implemented as using a file object could be problematic 197 given read() has to seek ahead to the first actual section to avoid 198 parsing errors""" 199 raise NotImplementedError, "Use read method instead" 141 200 self._parseReqDN() 142 201 143 202 144 def _ parseReqDN(self):145 """ ParseRequired DN parameters from the configuration file returning203 def _setReqDN(self): 204 """Set Required DN parameters from the configuration file returning 146 205 them in a dictionary 147 206 … … 150 209 # Nb. Match over line boundaries 151 210 try: 152 reqDnTxt = re.findall(self.__reqDnRE, self.__fileTxt, re.S)[0] 153 154 # Separate lines 155 reqDnLines = reqDnTxt.split(os.linesep) 156 157 # Match the '*_default' entries and make a dictionary 158 # 159 # Make sure comment lies are omitted - P J Kershaw 22/07/05 160 self.__reqDN = dict([re.split('_default\s*=\s*', line) \ 161 for line in reqDnLines \ 162 if re.match('[^#].*_default\s*=', line)]) 211 self.__reqDN = \ 212 { 213 'O': self.get('req_distinguished_name', 214 '0.organizationName_default'), 215 'OU': self.get('req_distinguished_name', 216 '0.organizationalUnitName_default') 217 } 163 218 except Exception, e: 164 219 raise OpenSSLConfigError, \ 165 "Error parsing content of OpenSSL config file \"%s\: %s" %\220 'Error setting content of Distinguished Name from file "%s": %s'%\ 166 221 (self.__filePath, str(e)) -
TI12-security/trunk/python/ndg.security.server/ndg/security/server/ca/__init__.py
r2148 r2150 31 31 32 32 # Certificate request generation 33 from M2Crypto import X509, RSA, EVP, m233 from M2Crypto import X509, BIO, RSA, EVP, m2 34 34 35 35 # For parsing of properties file … … 56 56 @cvar __validKeys: valid configuration property keywords used in file 57 57 and keyword input to __init__ and setProperties() 58 59 @type __gridCASubDir: string60 @cvar __gridCASubDir: sub-directory of globus user for CA settings61 58 62 59 @type __gridCAConfigFile: string … … 152 149 153 150 154 # Set-up CA directory - use in chkCAPassphrase() 155 if not os.environ.get('HOME'): 156 raise SimpleCAError, "Environment variable \"HOME\" is not set" 157 158 if 'openSSLConfigFilePath' not in self.__prop: 159 self.__openSSLConfig.filePath = os.path.join(os.environ['HOME'], 160 self.__gridCASubDir, 151 # Make config file path default setting if not already set 152 if 'openSSLConfigFilePath' not in self.__prop: 153 self.__openSSLConfig.filePath = os.path.join(\ 154 self.__openSSLConfig.caDir, 161 155 self.__gridCAConfigFile) 162 156 self.__openSSLConfig.read() … … 377 371 378 372 379 #_________________________________________________________________________ 380 def chkCAPassphrase(self, caPassphrase=None): 373 def chkCAPassphrase(self, caPassphrase=None): 374 375 if caPassphrase is None: 376 caPassphrase = self.__caPassphrase 377 else: 378 if not isinstance(caPassphrase, basestring): 379 raise SimpleCAPassPhraseError, \ 380 "CA Pass-phrase must be a valid string" 381 382 try: 383 priKeyFilePath = self.__openSSLConfig.get('CA_default', 384 'private_key') 385 priKeyFile = BIO.File(open(priKeyFilePath)) 386 387 except Exception, e: 388 raise SimpleCAError, \ 389 "Reading private key for pass-phrase check: %s" % e 390 try: 391 RSA.load_key_bio(priKeyFile,callback=lambda *ar,**kw:caPassphrase) 392 except: 393 SimpleCAPassPhraseError, "Invalid pass-phrase" 394 395 396 #_________________________________________________________________________ 397 def OldchkCAPassphrase(self, caPassphrase=None): 381 398 """Check given pass-phrase is correct for CA private key 382 399
Note: See TracChangeset
for help on using the changeset viewer.