Changeset 6276 for TI12-security/trunk/NDGSecurity
- Timestamp:
- 11/01/10 09:29:41 (10 years ago)
- Location:
- TI12-security/trunk/NDGSecurity/python
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/NDGSecurity/python/ndg_security
-
Property
svn:ignore
set to
*.egg-info
-
Property
svn:ignore
set to
-
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/__init__.py
r6069 r6276 255 255 raise AttributeError("SCRIPT_URL key not set in environ: " 256 256 "'mountPath' is set to None") 257 258 if self._mountPath != '/': 259 self._mountPath = self._mountPath.rstrip('/') 257 258 # Comment out as it breaks standard for URL trailing slash 259 # if self._mountPath != '/': 260 # self._mountPath = self._mountPath.rstrip('/') 260 261 261 262 def _getMountPath(self): -
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/provider/__init__.py
r6246 r6276 24 24 import paste.request 25 25 from paste.util.import_string import eval_import 26 import beaker.session 26 27 from openid.extensions import sreg, ax 27 28 from openid.server import server … … 163 164 trace=False, 164 165 renderingClass=None, 165 sregResponseHandler=None, 166 axResponseHandler=None, 167 authNInterface=AbstractAuthNInterface) 166 sregResponse=None, 167 axResponse=None, 168 authNInterface=AbstractAuthNInterface, 169 trustedRelyingParties=()) 168 170 169 171 defPaths = dict([(k, v) for k, v in defOpt.items() … … 184 186 APPROVE_RP_SUBMIT = "ApproveRelyingParty" 185 187 REJECT_RP_SUBMIT = "RejectRelyingParty" 188 189 TRUSTED_RELYINGPARTIES_SEP_PAT = re.compile(',\s*') 186 190 187 191 def __init__(self, app, app_conf=None, prefix=PARAM_PREFIX, **kw): … … 197 201 class variable 198 202 ''' 199 self._app = app 200 self._environ = {} 201 self._start_response = None 202 self._pathInfo = None 203 self._path = None 204 self.mountPath = '/' 203 super(OpenIDProviderMiddleware, self).__init__(app, {}) 204 # self._app = app 205 # self._environ = {} 206 # self._start_response = None 207 # self._pathInfo = None 208 # self._path = None 209 # self.mountPath = '/' 210 211 self.__charset = None 212 self.__paths = None 213 self.__base_url = None 214 self.__urls = None 215 self.__method = None 216 self.__sessionMiddlewareEnvironKeyName = None 217 self.__session = None 218 self.__oidserver = None 219 self.__query = {} 220 self.__sregResponse = None 221 self.__trustedRelyingParties = () 222 self.__axResponse = None 205 223 206 224 # See _createResponse method 207 self. oidResponse = None225 self.__oidResponse = None 208 226 209 227 opt = OpenIDProviderMiddleware.defOpt.copy() … … 220 238 opt.update(kw) 221 239 222 # Convert from string type where required 223 opt['charset'] = opt.get('charset', '') 224 opt['trace'] = opt.get('trace', 'false').lower() == 'true' 240 self.charset = opt['charset'] 241 242 # If True and debug log level is set display content of response 243 self._trace = opt.get('trace', 'false').lower() == 'true' 225 244 226 245 renderingClassVal = opt.get('renderingClass', None) … … 228 247 opt['renderingClass'] = eval_import(renderingClassVal) 229 248 230 sregResponse HandlerVal = opt.get('sregResponseHandler', None)231 if sregResponse HandlerVal:232 opt['sregResponse Handler'] = eval_import(sregResponseHandlerVal)249 sregResponseVal = opt.get('sregResponse', None) 250 if sregResponseVal: 251 opt['sregResponse'] = eval_import(sregResponseVal) 233 252 else: 234 opt['sregResponseHandler'] = None 235 236 axResponseHandlerVal = opt.get('axResponseHandler', None) 237 if axResponseHandlerVal: 238 opt['axResponseHandler'] = eval_import(axResponseHandlerVal) 239 else: 240 opt['axResponseHandler'] = None 253 opt['sregResponse'] = None 241 254 242 255 # Authentication interface to OpenID Provider - interface to for … … 288 301 for k, v in self.paths.items()]) 289 302 290 self.session_middleware = opt['session_middleware'] 291 292 if not opt['charset']: 293 self.charset = '' 294 else: 295 self.charset = '; charset=' + charset 296 297 # If True and debug log level is set display content of response 298 self._trace = opt['trace'] 303 self.sessionMiddlewareEnvironKeyName = opt['session_middleware'] 299 304 300 305 log.debug("opt=%r", opt) … … 326 331 # Callable for setting of Simple Registration attributes in HTTP header 327 332 # of response to Relying Party 328 self.sregResponse Handler = opt.get('sregResponseHandler', None)329 if self.sregResponse Handler and not callable(self.sregResponseHandler):333 self.sregResponse = opt.get('sregResponse', None) 334 if self.sregResponse and not callable(self.sregResponse): 330 335 raise OpenIDProviderMiddlewareError("Expecting callable for " 331 "sregResponse Handlerkeyword, "336 "sregResponse keyword, " 332 337 "got %r" % 333 self.sregResponse Handler)338 self.sregResponse) 334 339 335 340 # Class to handle OpenID Attribute Exchange (AX) requests from 336 341 # the Relying Party 337 342 axResponseClassName = opt.pop('axResponse_class', None) 338 if axResponseClassName is None: 339 # No AX Response handler set 340 self.axResponse = None 341 else: 343 if axResponseClassName is not None: 342 344 axResponseModuleFilePath = opt.pop('axResponse_moduleFilePath', 343 345 None) … … 347 349 348 350 try: 349 self. axResponse = instantiateClass(350 axResponseClassName,351 None,352 moduleFilePath=axResponseModuleFilePath,353 objectType=AXInterface,354 classProperties=axResponseProperties)351 self.__axResponse = instantiateClass( 352 axResponseClassName, 353 None, 354 moduleFilePath=axResponseModuleFilePath, 355 objectType=AXInterface, 356 classProperties=axResponseProperties) 355 357 except Exception, e: 356 358 log.error("Error instantiating AX interface: %s" % e) 357 359 raise 358 360 361 self.trustedRelyingParties = opt['trustedRelyingParties'] 362 359 363 # Instantiate OpenID consumer store and OpenID consumer. If you 360 364 # were connecting to a database, you would create the database … … 363 367 os.path.expandvars(opt['consumer_store_dirpath'])) 364 368 self.oidserver = server.Server(store, self.urls['url_openidserver']) 369 370 def getCharset(self): 371 return self.__charset 372 373 def getPaths(self): 374 return self.__paths 375 376 def getBase_url(self): 377 return self.__base_url 378 379 def getUrls(self): 380 return self.__urls 381 382 def getMethod(self): 383 return self.__method 384 385 def getSessionMiddlewareEnvironKeyName(self): 386 return self.__sessionMiddlewareEnvironKeyName 387 388 def getSession(self): 389 return self.__session 390 391 def setCharset(self, value): 392 # Convert from string type where required 393 if not value: 394 self.__charset = '' 395 elif isinstance(value, basestring): 396 self.__charset = '; charset=' + value 397 else: 398 raise TypeError('Expecting string type for "charset" attribute; ' 399 'got %r' % type(value)) 400 401 def setPaths(self, value): 402 if not isinstance(value, dict): 403 raise TypeError('Expecting dict type for ' 404 '"paths" attribute; got %r' % 405 type(value)) 406 self.__paths = value 407 408 def setBase_url(self, value): 409 if not isinstance(value, basestring): 410 raise TypeError('Expecting string type for ' 411 '"base_url" attribute; got %r' % 412 type(value)) 413 self.__base_url = value 414 415 def setUrls(self, value): 416 if not isinstance(value, dict): 417 raise TypeError('Expecting dict type for ' 418 '"urls" attribute; got %r' % 419 type(value)) 420 self.__urls = value 421 422 def setMethod(self, value): 423 if not isinstance(value, dict): 424 raise TypeError('Expecting dict type for ' 425 '"method" attribute; got %r' % 426 type(value)) 427 self.__method = value 428 429 def setSessionMiddlewareEnvironKeyName(self, value): 430 if not isinstance(value, basestring): 431 raise TypeError('Expecting string type for ' 432 '"sessionMiddlewareEnvironKeyName" attribute; ' 433 'got %r' % 434 type(value)) 435 self.__sessionMiddlewareEnvironKeyName = value 436 437 def setSession(self, value): 438 if not isinstance(value, beaker.session.SessionObject): 439 raise TypeError('Expecting beaker.session.SessionObject type for ' 440 '"session" attribute; got %r' % 441 type(value)) 442 443 self.__session = value 444 445 def getOidResponse(self): 446 return self.__oidResponse 447 448 def getSregResponse(self): 449 return self.__sregResponse 450 451 def getAxResponse(self): 452 return self.__axResponse 453 454 def getOidserver(self): 455 return self.__oidserver 456 457 def getQuery(self): 458 return self.__query 459 460 def getTrustedRelyingParties(self): 461 return self.__trustedRelyingParties 462 463 def setOidResponse(self, value): 464 if not isinstance(value, server.OpenIDResponse): 465 raise TypeError('Expecting OpenIDResponse type for ' 466 '"oidResponse" attribute; got %r' % 467 type(value)) 468 self.__oidResponse = value 469 470 def setSregResponse(self, value): 471 self.__sregResponse = value 472 473 def setAxResponse(self, value): 474 if not isinstance(value, AXInterface): 475 raise TypeError('Expecting AXInterface type for ' 476 '"axResponse" attribute; got %r' % 477 type(value)) 478 self.__axResponse = value 479 480 def setOidserver(self, value): 481 if not isinstance(value, server.Server): 482 raise TypeError('Expecting openid.server.server.Server type for ' 483 '"oidserver" attribute; got %r' % 484 type(value)) 485 self.__oidserver = value 486 487 def setQuery(self, value): 488 if not isinstance(value, dict): 489 raise TypeError('Expecting dict type for ' 490 '"query" attribute; got %r' % 491 type(value)) 492 self.__query = value 493 494 def setTrustedRelyingParties(self, value): 495 if isinstance(value, basestring): 496 pat = OpenIDProviderMiddleware.TRUSTED_RELYINGPARTIES_SEP_PAT 497 self.__trustedRelyingParties = tuple([i for i in pat.split(value)]) 498 499 elif isinstance(value, (list, tuple)): 500 self.__trustedRelyingParties = tuple(value) 501 else: 502 raise TypeError('Expecting list or tuple type for ' 503 '"trustedRelyingParties" attribute; got %r' % 504 type(value)) 365 505 366 506 @classmethod … … 504 644 @return: WSGI response 505 645 """ 506 if not environ.has_key(self.session _middleware):646 if not environ.has_key(self.sessionMiddlewareEnvironKeyName): 507 647 raise OpenIDProviderConfigError('The session middleware %r is not ' 508 648 'present. Have you set up the ' 509 649 'session middleware?' % 510 self.session_middleware)650 self.sessionMiddlewareEnvironKeyName) 511 651 512 652 # Beware path is a property and invokes the _setPath method 513 self.session = environ[self.session _middleware]653 self.session = environ[self.sessionMiddlewareEnvironKeyName] 514 654 self._render.session = self.session 515 655 … … 983 1123 except (OpenIDProviderMissingRequiredAXAttrs, 984 1124 OpenIDProviderMissingAXResponseHandler): 1125 log.error("%s type exception raised setting response following ID " 1126 "Approval: %s", e.__class__.__name__, 1127 traceback.format_exc()) 985 1128 response = self._render.errorPage(self.environ, 986 1129 self.start_response, … … 992 1135 993 1136 except OpenIDProviderReloginRequired, e: 1137 log.error("%s type exception raised setting response following ID " 1138 "Approval: %s", e.__class__.__name__, 1139 traceback.format_exc()) 994 1140 response = self._render.errorPage(self.environ, 995 1141 self.start_response, … … 1026 1172 return response 1027 1173 1028 def _identityIsAuth orized(self, oidRequest):1174 def _identityIsAuthenticated(self, oidRequest): 1029 1175 '''Check that a user is authorized i.e. does a session exist for their 1030 1176 username and if so does it correspond to the identity URL provided. … … 1043 1189 1044 1190 if oidRequest.idSelect(): 1045 log.debug("OpenIDProviderMiddleware._identityIsAuth orized - "1191 log.debug("OpenIDProviderMiddleware._identityIsAuthenticated - " 1046 1192 "ID Select mode set but user is already logged in") 1047 1193 return True … … 1053 1199 1054 1200 if oidRequest.identity != identityURI: 1055 log.debug("OpenIDProviderMiddleware._identityIsAuth orized - user "1201 log.debug("OpenIDProviderMiddleware._identityIsAuthenticated - user " 1056 1202 "is already logged in with a different ID=%s and " 1057 1203 "identityURI=%s" % … … 1059 1205 return False 1060 1206 1061 log.debug("OpenIDProviderMiddleware._identityIsAuth orized - "1207 log.debug("OpenIDProviderMiddleware._identityIsAuthenticated - " 1062 1208 "user is logged in with ID matching ID URI") 1063 1209 return True … … 1079 1225 return approvedRoots.get(trust_root) is not None 1080 1226 1227 def _isConfiguredTrustedRoot(self, trust_root): 1228 """the Relying Party is one of a 1229 list of RPs set in the start up configuration as not needing 1230 approval. This could be for example sites within the same 1231 organisation as this Provider 1232 1233 @type trust_root: dict 1234 @param trust_root: keyed by trusted root (Relying Party) URL and 1235 containing string item 'always' if approved 1236 @rtype: bool 1237 @return: True - trust has already been approved, False - trust root is 1238 not approved 1239 """ 1240 return trust_root in self.trustedRelyingParties 1241 1081 1242 def _addSRegResponse(self, oidRequest): 1082 1243 '''Add Simple Registration attributes to response to Relying Party … … 1085 1246 @param oidRequest: OpenID Check ID Request object''' 1086 1247 1087 if self.sregResponse Handleris None:1248 if self.sregResponse is None: 1088 1249 # No Simple Registration response object was set 1089 1250 return … … 1093 1254 # Callout to external callable sets additional user attributes to be 1094 1255 # returned in response to Relying Party 1095 sreg_data = self.sregResponse Handler(self.session.get(1256 sreg_data = self.sregResponse(self.session.get( 1096 1257 OpenIDProviderMiddleware.USERNAME_SESSION_KEYNAME)) 1097 1258 sreg_resp = sreg.SRegResponse.extractResponse(sreg_req, sreg_data) … … 1117 1278 if len(requiredAttr) > 0: 1118 1279 msg = ("Relying party requires these attributes: %s; but No" 1119 "Attribute exchange handler 'axResponse Handler' has "1280 "Attribute exchange handler 'axResponse' has " 1120 1281 "been set" % requiredAttr) 1121 1282 log.error(msg) … … 1186 1347 self.session.save() 1187 1348 1188 if self._identityIsAuth orized(oidRequest):1349 if self._identityIsAuthenticated(oidRequest): 1189 1350 1190 1351 # User is logged in - check for ID Select type request i.e. the … … 1192 1353 # full OpenID URL. In this case, the identity they wish to use must 1193 1354 # be confirmed. 1194 if oidRequest.idSelect(): 1355 isConfiguredTrustedRoot = self._isConfiguredTrustedRoot( 1356 oidRequest.trust_root) 1357 if oidRequest.idSelect() and not isConfiguredTrustedRoot: 1195 1358 # OpenID identifier must be confirmed 1196 1359 return self.do_decide(self.environ, self.start_response) 1197 1360 1198 elif self._trustRootIsAuthorized(oidRequest.trust_root): 1361 elif (self._trustRootIsAuthorized(oidRequest.trust_root) or 1362 isConfiguredTrustedRoot): 1363 1199 1364 # User entered their full OpenID URL and they have previously 1200 # approved this Relying Party 1365 # approved this Relying Party OR the Relying Party is one of a 1366 # list of RPs set in the start up configuration as not needing 1367 # approval. This could be for example sites within the same 1368 # organisation as this Provider 1201 1369 try: 1202 self._createResponse(oidRequest) 1370 identityURI = self.session[ 1371 OpenIDProviderMiddleware.IDENTITY_URI_SESSION_KEYNAME 1372 ] 1373 self._createResponse(oidRequest, identifier=identityURI) 1203 1374 1204 1375 except (OpenIDProviderMissingRequiredAXAttrs, … … 1311 1482 return [] 1312 1483 1484 charset = property(getCharset, setCharset, None, "Charset's Docstring") 1485 1486 paths = property(getPaths, setPaths, None, "Dictionary of Paths for the app") 1487 1488 base_url = property(getBase_url, setBase_url, None, "Base URL for the app") 1489 1490 urls = property(getUrls, setUrls, None, "dictionary of URLs for app") 1491 1492 method = property(getMethod, setMethod, None, 1493 "Method name keyed from requested URL") 1494 1495 sessionMiddlewareEnvironKeyName = property( 1496 getSessionMiddlewareEnvironKeyName, 1497 setSessionMiddlewareEnvironKeyName, 1498 None, 1499 "environ key name for Beaker Session " 1500 "middleware") 1501 1502 session = property(getSession, setSession, None, "Session's Docstring") 1503 1504 oidResponse = property(getOidResponse, 1505 setOidResponse, 1506 None, 1507 "OpenID response object") 1508 1509 sregResponse = property(getSregResponse, 1510 setSregResponse, 1511 None, 1512 "SReg response handler class") 1513 1514 axResponse = property(getAxResponse, setAxResponse, None, 1515 "Attribute Exchange response object") 1516 1517 oidserver = property(getOidserver, setOidserver, None, 1518 "OpenID server instance") 1519 1520 query = property(getQuery, setQuery, None, 1521 "dictionary of HTML query parameters") 1522 1523 trustedRelyingParties = property(getTrustedRelyingParties, 1524 setTrustedRelyingParties, 1525 None, 1526 "Relying Parties trusted by this Provider") 1527 1313 1528 1314 1529 class RenderingInterfaceError(Exception): -
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/provider/axinterface/__init__.py
r6069 r6276 38 38 def __init__(self, **cfg): 39 39 """Add custom settings from the OpenID Provider's 40 openid.provider.axResponse Handler.* settings contained in the host40 openid.provider.axResponse.* settings contained in the host 41 41 Paste ini file 42 42 -
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/provider/axinterface/csv.py
r6069 r6276 167 167 ', '.join(missingAttributeURIs)) 168 168 169 # Add the required attributes 170 for requiredAttributeURI in requiredAttributeURIs: 171 log.info("Adding required AX parameter %s=%s ...", 172 requiredAttributeURI, 173 userAttributeMap[requiredAttributeURI]) 174 175 ax_resp.addValue(requiredAttributeURI, 176 userAttributeMap[requiredAttributeURI]) 177 178 # Append requested attribute if available 169 # Add the requested attributes 179 170 for requestedAttributeURI in ax_req.requested_attributes.keys(): 180 171 if requestedAttributeURI in self.attributeNames: -
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/relyingparty/__init__.py
r6069 r6276 16 16 import httplib # to get official status code messages 17 17 import urllib # decode quoted URI in query arg 18 import urllib2 # SSL based whitelisting 18 19 from urlparse import urlsplit, urlunsplit 19 20 20 21 21 from paste.request import parse_querystring, parse_formvars … … 24 24 from beaker.middleware import SessionMiddleware 25 25 26 # SSL based whitelisting 27 from M2Crypto import SSL 28 from M2Crypto.m2urllib2 import build_opener, HTTPSHandler 29 from openid.fetchers import setDefaultFetcher, Urllib2Fetcher 30 31 from ndg.security.common.utils.classfactory import instantiateClass 26 32 from ndg.security.server.wsgi import NDGSecurityMiddlewareBase 27 33 from ndg.security.server.wsgi.authn import AuthnRedirectMiddleware 28 from ndg.security.common.utils.classfactory import instantiateClass 34 from ndg.security.server.wsgi.openid.relyingparty.validation import ( 35 SSLIdPValidationDriver) 29 36 30 37 … … 48 55 ''' 49 56 sslPropertyDefaults = { 50 'certFilePath': '', 51 'priKeyFilePath': None, 52 'priKeyPwd': None, 53 'caCertDirPath': None, 54 'providerWhitelistFilePath': None 57 'idpWhitelistConfigFilePath': None 55 58 } 56 59 propertyDefaults = { 57 'sslPeerCertAuthN': True,58 60 'signinInterfaceMiddlewareClass': None, 59 61 'baseURL': '' … … 79 81 format of propertyDefaults class variable""" 80 82 81 # Default to set SSL peer cert authN where no flag is set in the config 82 # To override, it must explicitly be set to False in the config 83 if app_conf.get('sslPeerCertAuthN', 'true').lower() != 'false': 84 85 # Set parameters for SSL client connection to OpenID Provider Yadis 86 # retrieval URI 87 for paramName in self.__class__.sslPropertyDefaults: 88 paramDefault = self.__class__.sslPropertyDefaults[paramName] 89 setattr(self, 90 paramName, 91 app_conf.get(prefix+paramName, paramDefault)) 92 93 self._initSSLPeerAuthN() 83 # Whitelisting of IDPs. If no config file is set, no validation is 84 # executed 85 idpWhitelistConfigFilePath = app_conf.get( 86 prefix + 'idpWhitelistConfigFilePath') 87 if idpWhitelistConfigFilePath is not None: 88 self._initIdPValidation(idpWhitelistConfigFilePath) 94 89 95 90 # Check for sign in template settings … … 195 190 referrerPathInfo = urlsplit(referrer)[2] 196 191 197 if referrer and \198 not referrerPathInfo.endswith(self._authKitVerifyPath) and \199 not referrerPathInfo.endswith(self._authKitProcessPath):192 if (referrer and 193 not referrerPathInfo.endswith(self._authKitVerifyPath) and 194 not referrerPathInfo.endswith(self._authKitProcessPath)): 200 195 # Subvert authkit.authenticate.open_id.AuthOpenIDHandler.process 201 196 # reassigning it's session 'referer' key to the URI specified in … … 246 241 return self._app(environ, _start_response) 247 242 248 def _init SSLPeerAuthN(self):243 def _initIdPValidation(self, idpWhitelistConfigFilePath): 249 244 """Initialise M2Crypto based urllib2 HTTPS handler to enable SSL 250 245 authentication of OpenID Providers""" … … 252 247 "Provider ...") 253 248 254 def verifySSLPeerCertCallback(preVerifyOK, x509StoreCtx): 255 '''SSL verify callback function used to control the behaviour when 256 the SSL_VERIFY_PEER flag is set 257 258 http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html 259 260 @type preVerifyOK: int 261 @param preVerifyOK: If a verification error is found, this 262 parameter will be set to 0 263 @type x509StoreCtx: M2Crypto.X509_Store_Context 264 @param x509StoreCtx: locate the certificate to be verified and 265 perform additional verification steps as needed 266 @rtype: int 267 @return: controls the strategy of the further verification process. 268 - If verify_callback returns 0, the verification process is 269 immediately stopped with "verification failed" state. If 270 SSL_VERIFY_PEER is set, a verification failure alert is sent to the 271 peer and the TLS/SSL handshake is terminated. 272 - If verify_callback returns 1, the verification process is 273 continued. 274 If verify_callback always returns 1, the TLS/SSL handshake will not 275 be terminated with respect to verification failures and the 276 connection 277 will be established. The calling process can however retrieve the 278 error code of the last verification error using 279 SSL_get_verify_result or by maintaining its own error storage 280 managed by verify_callback. 281 ''' 282 if preVerifyOK == 0: 283 # Something is wrong with the certificate don't bother 284 # proceeding any further 285 log.error("verifyCallback: pre-verify OK flagged an error " 286 "with the peer certificate, returning error state " 287 "to caller ...") 288 return preVerifyOK 289 290 x509Cert = x509StoreCtx.get_current_cert() 291 x509Cert.get_subject() 292 x509CertChain = x509StoreCtx.get1_chain() 293 for cert in x509CertChain: 294 subject = cert.get_subject() 295 dn = subject.as_text() 296 log.debug("verifyCallback: dn = %r", dn) 297 298 # If all is OK preVerifyOK will be 1. Return this to the caller to 299 # that it's OK to proceed 300 return preVerifyOK 301 302 # Imports here so that if SSL Auth is not set the app will not need 303 # these packages 304 import urllib2 305 from M2Crypto import SSL 306 from M2Crypto.m2urllib2 import build_opener 307 from openid.fetchers import setDefaultFetcher, Urllib2Fetcher 308 309 # Create a context specifying verification of the peer but with an 310 # additional callback function 311 ctx = SSL.Context() 312 ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 313 9, 314 callback=verifySSLPeerCertCallback) 315 316 # Point to a directory containing CA certificates. These must be named 317 # in their hashed form as expected by the OpenSSL API. Use c_rehash 318 # utility to generate names or in the CA directory: 319 # 320 # $ for i in *.crt *.pem; do ln -s $i $(openssl x509 -hash -noout -in $i).0; done 321 ctx.load_verify_locations(capath=self.caCertDirPath) 322 323 # Load this client's certificate and private key to enable the peer 324 # OpenID Provider to authenticate it 325 ctx.load_cert(self.certFilePath, 326 keyfile=self.priKeyFilePath, 327 callback=lambda *arg, **kw: self.priKeyPwd) 249 idPValidationDriver = SSLIdPValidationDriver( 250 idpConfigFilePath=idpWhitelistConfigFilePath) 251 252 # def verifySSLPeerCertCallback(preVerifyOK, x509StoreCtx): 253 # '''SSL verify callback function used to control the behaviour when 254 # the SSL_VERIFY_PEER flag is set 255 # 256 # http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html 257 # 258 # @type preVerifyOK: int 259 # @param preVerifyOK: If a verification error is found, this 260 # parameter will be set to 0 261 # @type x509StoreCtx: M2Crypto.X509_Store_Context 262 # @param x509StoreCtx: locate the certificate to be verified and 263 # perform additional verification steps as needed 264 # @rtype: int 265 # @return: controls the strategy of the further verification process. 266 # - If verify_callback returns 0, the verification process is 267 # immediately stopped with "verification failed" state. If 268 # SSL_VERIFY_PEER is set, a verification failure alert is sent to the 269 # peer and the TLS/SSL handshake is terminated. 270 # - If verify_callback returns 1, the verification process is 271 # continued. 272 # If verify_callback always returns 1, the TLS/SSL handshake will not 273 # be terminated with respect to verification failures and the 274 # connection 275 # will be established. The calling process can however retrieve the 276 # error code of the last verification error using 277 # SSL_get_verify_result or by maintaining its own error storage 278 # managed by verify_callback. 279 # ''' 280 # if preVerifyOK == 0: 281 # # Something is wrong with the certificate don't bother 282 # # proceeding any further 283 # log.error("verifyCallback: pre-verify OK flagged an error " 284 # "with the peer certificate, returning error state " 285 # "to caller ...") 286 # return preVerifyOK 287 # 288 # x509Cert = x509StoreCtx.get_current_cert() 289 # x509Cert.get_subject() 290 # x509CertChain = x509StoreCtx.get1_chain() 291 # for cert in x509CertChain: 292 # subject = cert.get_subject() 293 # dn = subject.as_text() 294 # log.debug("verifyCallback: dn = %r", dn) 295 # 296 # # If all is OK preVerifyOK will be 1. Return this to the caller to 297 # # that it's OK to proceed 298 # return preVerifyOK 299 # 300 # 301 # # Create a context specifying verification of the peer but with an 302 # # additional callback function 303 # ctx = SSL.Context() 304 # ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 305 # 9, 306 # callback=verifySSLPeerCertCallback) 307 # 308 # # Point to a directory containing CA certificates. These must be named 309 # # in their hashed form as expected by the OpenSSL API. Use c_rehash 310 # # utility to generate names or in the CA directory: 311 # # 312 # # $ for i in *.crt *.pem; do ln -s $i $(openssl x509 -hash -noout -in $i).0; done 313 # ctx.load_verify_locations(capath=self.caCertDirPath) 314 # 315 # # Load this client's certificate and private key to enable the peer 316 # # OpenID Provider to authenticate it 317 # ctx.load_cert(self.certFilePath, 318 # keyfile=self.priKeyFilePath, 319 # callback=lambda *arg, **kw: self.priKeyPwd) 328 320 329 321 # Force Python OpenID library to use Urllib2 fetcher instead of the … … 331 323 setDefaultFetcher(Urllib2Fetcher()) 332 324 333 log.debug("Adding the M2Crypto SSL handler to urllib2's list of " 334 "handlers...") 335 urllib2.install_opener(build_opener(ssl_context=ctx)) 336 325 # log.debug("Adding the M2Crypto SSL handler to urllib2's list of " 326 # "handlers...") 327 # urllib2.install_opener(build_opener(ssl_context=ctx)) 328 log.debug("Setting the M2Crypto SSL handler ...") 329 330 opener = urllib2.OpenerDirector() 331 opener.add_handler(FlagHttpsOnlyHandler()) 332 opener.add_handler(HTTPSHandler(idPValidationDriver.ctx)) 333 334 urllib2.install_opener(opener) 335 336 337 class FlagHttpsOnlyHandler(urllib2.AbstractHTTPHandler): 338 '''Raise an exception for any other protocol than https''' 339 def unknown_open(self, req): 340 """Signal to caller that default handler is not supported""" 341 raise urllib2.URLError("Only HTTPS based OpenID Providers " 342 "are supported") 343 344 337 345 class SigninInterfaceError(Exception): 338 346 """Base class for SigninInterface exceptions -
TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/relyingparty/validation.py
r6069 r6276 261 261 '''Interface class for implementing OpenID Provider validators for a 262 262 Relying Party to call''' 263 __slots__ = () 263 264 264 265 def __init__(self): … … 285 286 286 287 class SSLClientAuthNValidator(SSLIdPValidator): 288 """HTTPS based validation with the addition that this client can provide 289 a certificate to the peer enabling mutual authentication 290 """ 287 291 PARAMETERS = { 288 292 'configFilePath': basestring, … … 292 296 'priKeyPwd': basestring 293 297 } 298 __slots__ = {} 299 __slots__.update(PARAMETERS) 300 __slots__.update({'validIdPNames': []}) 294 301 295 302 def __init__(self): 296 303 """Set-up default SSL context for HTTPS requests""" 304 self.validIdPNames = [] 305 297 306 for p in SSLClientAuthNValidator.PARAMETERS: 298 setattr(self, p, None) 299 307 setattr(self, p, '') 308 309 def __setattr__(self, name, value): 310 if (name in SSLClientAuthNValidator.PARAMETERS and 311 not isinstance(value, SSLClientAuthNValidator.PARAMETERS[name])): 312 raise TypeError('Invalid type %r for parameter "%s" expecting ' 313 '%r ' % 314 (type(value), 315 name, 316 SSLClientAuthNValidator.PARAMETERS[name])) 317 318 super(SSLClientAuthNValidator, self).__setattr__(name, value) 319 300 320 def initialize(self, ctx, **parameters): 301 321 '''@raise ConfigException:''' 302 322 for name, val in parameters.items(): 303 if name not in SSLClientAuthNValidator.PARAMETERS:304 raise AttributeError('Invalid parameter name "%s". Valid '305 'names are %r' % (name,306 SSLClientAuthNValidator.PARAMETERS.keys()))307 308 if not isinstance(val, SSLClientAuthNValidator.PARAMETERS[name]):309 raise TypeError('Invalid type %r for parameter "%s" expecting '310 '%r ' %311 (type(val),312 name,313 SSLClientAuthNValidator.PARAMETERS[name]))314 315 323 setattr(self, name, os.path.expandvars(val)) 316 324 … … 349 357 x509Cert = X509Cert.fromM2Crypto(x509StoreCtx.get_current_cert()) 350 358 commonName = x509Cert.dn['CN'] 359 360 361 x509CertChain = x509StoreCtx.get1_chain() 362 for cert in x509CertChain: 363 subject = cert.get_subject() 364 dn = subject.as_text() 365 log.debug("verifyCallback: dn = %r", dn) 351 366 352 367 # If all is OK preVerifyOK will be 1. Return this to the caller to … … 580 595 IDP_VALIDATOR_BASE_CLASS = SSLIdPValidator 581 596 582 def __init__(self, idpConfigFilePath=None ):597 def __init__(self, idpConfigFilePath=None, installOpener=False): 583 598 super(SSLIdPValidationDriver, self).__init__() 584 599 … … 592 607 callback=self) 593 608 594 urllib2.install_opener(build_opener(ssl_context=self.ctx)) 609 if installOpener: 610 urllib2.install_opener(build_opener(ssl_context=self.ctx)) 595 611 596 612 if idpConfigFilePath is not None: -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/__init__.py
r6069 r6276 9 9 __contact__ = "Philip.Kershaw@stfc.ac.uk" 10 10 __revision__ = "$Id: $" 11 11 12 12 13 class AuthZTestApp(object): -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/authz_lite/securityservices.ini
r6271 r6276 123 123 124 124 openid.relyingparty.baseURL = %(authkit.openid.baseurl)s 125 openid.relyingparty.certFilePath = %(testConfigDir)s/pki/localhost.crt 126 openid.relyingparty.priKeyFilePath = %(testConfigDir)s/pki/localhost.key 127 openid.relyingparty.priKeyPwd = 128 openid.relyingparty.caCertDirPath = %(testConfigDir)s/ca 129 openid.relyingparty.providerWhitelistFilePath = 125 openid.relyingparty.idpWhitelistConfigFilePath = %(here)s/openidrelyingparty/ssl-idp-validator.xml 130 126 openid.relyingparty.signinInterfaceMiddlewareClass = ndg.security.server.wsgi.openid.relyingparty.signin_interface.genshi.GenshiSigninTemplate 131 127 #openid.relyingparty.signinInterface.staticContentRootDir = %(here)s/openidrelyingparty/public … … 284 280 http://openid.net/schema/namePerson/last 285 281 http://openid.net/schema/contact/internet/email 282 283 openid.provider.trustedRelyingParties=https://localhost:7443, https://ndg.somewhere.ac.uk, 284 https://badc.somewhere.ac.uk 286 285 287 286 #______________________________________________________________________________ -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/authz_lite/securityservicesapp.py
r6069 r6276 15 15 from OpenSSL import SSL 16 16 17 from ndg.security.test.unit import BaseTestCase 17 from ndg.security.test.unit import BaseTestCase, TEST_CONFIG_DIR 18 18 from ndg.security.test.unit.wsgi import PasteDeployAppServer 19 19 20 20 INI_FILEPATH = 'securityservices.ini' 21 22 os.environ['NDGSEC_INTEGRATION_TEST_DIR'] = os.path.dirname(os.path.dirname( 23 __file__)) 24 os.environ[BaseTestCase.configDirEnvVarName] = TEST_CONFIG_DIR 21 25 22 26 # To start run -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/combinedservices/services.ini
r5656 r6276 419 419 420 420 421 #openid.provider.sregResponse Handler=ndg.security.server.pylons.container.lib.openid_provider_util:esgSRegResponseHandler421 #openid.provider.sregResponse=ndg.security.server.pylons.container.lib.openid_provider_util:esgSregResponse 422 422 #openid.provider.axResponseHandler=ndg.security.server.pylons.container.lib.openid_provider_util:esgAXResponseHandler 423 423 -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/openid/securityservices.ini
r5648 r6276 276 276 277 277 278 #openid.provider.sregResponse Handler=ndg.security.server.pylons.container.lib.openid_provider_util:esgSRegResponseHandler278 #openid.provider.sregResponse=ndg.security.server.pylons.container.lib.openid_provider_util:esgSregResponse 279 279 #openid.provider.axResponseHandler=ndg.security.server.pylons.container.lib.openid_provider_util:esgAXResponseHandler 280 280 -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/openidprovider/securityservices.ini
r5648 r6276 242 242 243 243 244 #openid.provider.sregResponse Handler=ndg.security.server.pylons.container.lib.openid_provider_util:esgSRegResponseHandler244 #openid.provider.sregResponse=ndg.security.server.pylons.container.lib.openid_provider_util:esgSregResponse 245 245 #openid.provider.axResponseHandler=ndg.security.server.pylons.container.lib.openid_provider_util:esgAXResponseHandler 246 246 -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/unit/__init__.py
r6067 r6276 1 1 """NDG Security unit test package 2 2 3 NERC Data 3 NERC DataGrid Project 4 4 """ 5 5 __author__ = "P J Kershaw" -
TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/unit/openid/relyingparty/validation/test_validation.py
r6069 r6276 15 15 import unittest 16 16 from ndg.security.test.unit import BaseTestCase, mkDataDirPath 17 from ndg.security.server.wsgi.openid.relyingparty.validation import \18 IdPValidator, IdPValidationDriver, IdPInvalidException, \19 SSLIdPValidationDriver, SSLClientAuthNValidator 17 from ndg.security.server.wsgi.openid.relyingparty.validation import ( 18 IdPValidator, IdPValidationDriver, IdPInvalidException, 19 SSLIdPValidationDriver, SSLClientAuthNValidator) 20 20 21 21
Note: See TracChangeset
for help on using the changeset viewer.