def authenticate(openid_uri, password): try: filepath = utils.user_url_to_filepath(openid_uri) host = urlparse(openid_uri.strip()).netloc; user = openid_uri.rsplit('/', 1)[1] except IndexError: raise MyProxyClientError('Invalid OpenID identifier') if not host or not user: raise MyProxyClientError('Invalid OpenID identifier') try: myproxy = MyProxyClient(hostname=host) credentials = myproxy.logon(user, password, bootstrap=True) cert_filepath = utils.user_cert_file(openid_uri) dir = os.path.dirname(cert_filepath); if not os.path.exists(dir): os.makedirs(dir) with open(cert_filepath, 'w') as fd: fd.write(credentials[0]) fd.write(credentials[1]) except socket.gaierror: raise MyProxyClientError('Invalid OpenID identifier')
class MyProxyUtils(object): def __init__(self): self.config = config.read_config() self.cacertdir = os.path.expanduser("~/.esg/certificates") self.credsfile = os.path.expanduser("~/.esg/credentials.pem") self.myproxy = MyProxyClient(hostname=self.config['nodes']['idp_node']) self.myproxy._setCACertDir(self.cacertdir) def get_trustroots(self): # Get trust roots self.trustRoots = self.myproxy.getTrustRoots( self.config['account']['username'], self.config['account']['password'], writeToCACertDir=True, bootstrap=True) def get_credentials(self): # Get credentials (and trustroots) self.credentials = self.myproxy.logon( self.config['account']['username'], self.config['account']['password']) # Write Credentials with open(self.credsfile, 'w') as f: f.write(self.credentials[0] + self.credentials[1]) os.chmod(self.credsfile, self.myproxy.PROXY_FILE_PERMISSIONS) def delete_credentials(self): # Delete credentials file if os.path.exists(self.credsfile): os.remove(self.credsfile) def delete_trustroots(self): # Delete trustroots and cacert directory if os.path.exists(self.cacertdir): shutil.rmtree(self.cacertdir)
def test02SetProperties(self): client = MyProxyClient() try: client.port = None self.fail("Expecting AttributeError raised from port set to " "invalid type") except TypeError: pass client.port = 8000 client.hostname = '127.0.0.1' client.serverDN = '/O=NDG/OU=BADC/CN=raphael' client.proxyCertMaxLifetime = 80000 client.proxyCertLifetime = 70000 try: client.openSSLConfFilePath = mkPath('ssl.cnf') self.fail("Expecting OpenSSLConfigError raised for invalid file " "'ssl.cnf'") except OpenSSLConfigError: pass client.caCertDir = mkPath('/etc/grid-security/certificates') self.assertTrue(client.port == 8000) self.assertTrue(client.hostname == '127.0.0.1') self.assertTrue(client.serverDN == '/O=NDG/OU=BADC/CN=raphael') self.assertTrue(client.proxyCertMaxLifetime == 80000) self.assertTrue(client.proxyCertLifetime == 70000) self.assertTrue(client.openSSLConfFilePath == mkPath('ssl.cnf')) self.assertTrue( client.caCertDir == mkPath('/etc/grid-security/certificates'))
def setUp(self): super(MyProxyClientLiveTestCase, self).setUp() configParser = CaseSensitiveConfigParser() configFilePath = path.join(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], MyProxyClientLiveTestCase.CONFIG_FILENAME) configParser.read(configFilePath) self.cfg = {} for section in configParser.sections(): self.cfg[section] = dict(configParser.items(section)) configFilePath = path.expandvars(self.cfg['setUp']['cfgFilePath']) self.clnt = MyProxyClient(cfgFilePath=configFilePath) # Get trust roots bootstrapping trust ready for test self.trustRoots = self.clnt.getTrustRoots(writeToCACertDir=True, bootstrap=True) # Keep a copy of files stored ready for tearDown tidy up self.trustRootFiles = [] dirContents = os.listdir(self.clnt.caCertDir) for fileName in self.trustRoots: self.assertTrue(fileName in dirContents) file_path = os.path.join(self.clnt.caCertDir, fileName) self.trustRootFiles.append(file_path)
def __init__(self, app): super(MyProxyProvisionedSessionMiddleware, self).__init__(app) self.__myProxyClient = MyProxyClient() self.__certExpiryOffset = self.__class__.DEFAULT_CERT_EXPIRY_OFFSET self.__myProxyClientSSLCertFile = None self.__myProxyClientSSLKeyFile = None self.__myProxyClientSSLKeyFilePassphrase = None
def get_slcs_token(context, request): originURL = request.POST['url'] proxy_username = request.POST['myproxy_username'] proxy_password = request.POST['myproxy_password'] c = MyProxyClient(hostname='myproxy2.arcs.org.au', port= 7512, serverDN='/C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au') success, err, field = c.info(proxy_username, userCertFile=CERTIFICATE, userKeyFile=KEY, userPassphrase=lambda *a: '') '''
def test03_ssl_verification(self): # SSL verification callback # Ensure no relevant environment variables are set which might affect # the result try: serverDN = os.environ.get( MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME) if serverDN is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME] serverName = os.environ.get(MyProxyClient.MYPROXY_SERVER_ENVVARNAME) if serverName is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_ENVVARNAME] client = MyProxyClient() connection = None errorStatus = False successStatus = True errorDepth = 0 valid_peer_cert_str = open(self.__class__.HOSTCERT_FILEPATH).read() valid_peer_cert = crypto.load_certificate(crypto.FILETYPE_PEM, valid_peer_cert_str) # This would normally be called implicitly during the SSL handshake status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) expired_peer_cert_str = open( self.__class__.EXPIREDCERT_FILEPATH).read() expired_peer_cert = crypto.load_certificate(crypto.FILETYPE_PEM, expired_peer_cert_str) # Match based on full DN instead - this takes precedence over # hostname match client.serverDN = self.__class__.HOSTCERT_DN status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) # Check for expired certificate status = client.ssl_verification(connection, expired_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == errorStatus) finally: if serverDN is not None: os.environ[MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME ] = serverDN if serverName is not None: os.environ[MyProxyClient.MYPROXY_SERVER_ENVVARNAME ] = serverName
def renew_certificate (host,port,username,password): sdlog.info("SDMYPROX-002","Renew certificate..") # we need a mkdir here to prevent 'No such file or directory' myproxyclient error (see TAGFERE5435 for more info) sd=sdconfig.get_security_dir() if not os.path.isdir(sd): os.makedirs(sd) # currently, we set bootstrap option everytime # # TODO: change this to set only the first time (i.e. if .esg/certificates is empty) # bootstrap=True # currently, we set trustroots option everytime updateTrustRoots=True authnGetTrustRootsCall=False # TODO: maybe add option in 'synda certificate' to use specify another path for cadir (for debugging purpose) #ROOT_TRUSTROOT_DIR = '/etc/grid-security/certificates' #USER_TRUSTROOT_DIR = '~/.globus/certificates' # set env. os.environ['ESGF_CREDENTIAL']=sdconfig.esgf_x509_proxy os.environ['ESGF_CERT_DIR']=sdconfig.esgf_x509_cert_dir os.environ['X509_CERT_DIR']=sdconfig.esgf_x509_cert_dir if 'X509_USER_PROXY' in os.environ: del os.environ['X509_USER_PROXY'] #if 'GLOBUS_LOCATION' in os.environ: # del os.environ['GLOBUS_LOCATION'] # main myproxy_clnt = MyProxyClient(hostname=host, port=port, caCertDir=sdconfig.esgf_x509_cert_dir, proxyCertLifetime=43200) # 12 hours # credname=credname creds=myproxy_clnt.logon(username, password, bootstrap=bootstrap, updateTrustRoots=updateTrustRoots, authnGetTrustRootsCall=authnGetTrustRootsCall) # store cert on disk fout = open(sdconfig.esgf_x509_proxy, 'w') for cred in creds: fout.write(cred) fout.close()
def authenticate(request): if request.method != 'POST': return Response('Error: GET is not supported') data = json.loads(request.body.decode('utf-8')) openid = data.get('openid') password = data.get('password') (server, username) = utils.decompose_openid(openid) # Get X.509 certificate chain from MyProxy server log.info("Getting X.509 certificate from %s for %s" % (server, username)) myproxy_client = MyProxyClient(hostname=server) cred_chain_pem_tuple = None try: cred_chain_pem_tuple = myproxy_client.logon(username, password, lifetime=7*24*3600) except Exception as e: request.response.status = 400 return {'status': 'Error', 'message': '%s' % e} cred_chain_pem = '' for e in cred_chain_pem_tuple: cred_chain_pem += e cert_pem = cred_chain_pem_tuple[0] # Get 'Not After' date cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem) not_after_asn1 = cert.get_notAfter() not_after = not_after_asn1.decode() dt = datetime.strptime(not_after, '%Y%m%d%H%M%SZ') # Check the publisher role in X509v3 extension 1.2.3.4.4.3.2.1.7.8 if not authentication.is_publisher(openid, cert): request.response.status = 400 return {'status': 'Error', 'message': 'The user does not have the publisher role'} # Store the X.509 certificate chain in a tmp file, so it can be used later by esgcet cred_file = open('/tmp/x509in_%s_%s' % (server, username), 'w') cred_file.write(cred_chain_pem) cred_file.close() # Add or update Publisher object in the database publisher = DBSession.query(Publisher).filter(Publisher.openid==openid).first() if publisher: publisher.x509_pem = cred_chain_pem publisher.expiration = dt else: publisher = Publisher(openid=openid, x509_pem=cred_chain_pem, expiration=dt) DBSession.add(publisher) # Save openid in auth_tk cookie headers = remember(request, openid) resp = Response() resp.headers = headers return resp
def test02SetProperties(self): client = MyProxyClient() try: client.port = None self.fail("Expecting AttributeError raised from port set to " "invalid type") except TypeError: pass client.port = 8000 client.hostname = '127.0.0.1' client.serverDN = '/O=NDG/OU=BADC/CN=raphael' client.proxyCertMaxLifetime = 80000 client.proxyCertLifetime = 70000 try: client.openSSLConfFilePath = mkPath('ssl.cnf') self.fail("Expecting OpenSSLConfigError raised for invalid file " "'ssl.cnf'") except OpenSSLConfigError: pass client.caCertDir = mkPath('/etc/grid-security/certificates') self.assert_(client.port == 8000) self.assert_(client.hostname == '127.0.0.1') self.assert_(client.serverDN == '/O=NDG/OU=BADC/CN=raphael') self.assert_(client.proxyCertMaxLifetime == 80000) self.assert_(client.proxyCertLifetime == 70000) self.assert_(client.openSSLConfFilePath == mkPath('ssl.cnf')) self.assert_( client.caCertDir == mkPath('/etc/grid-security/certificates'))
def logon(config, myproxy_username=None, myproxy_password=None, myproxy_hostname=None): """ Use MyProxyClient to generate a certificate for publication. Generate appropriate directories if not exists :param config config: Configuration instance, e.g. from getConfig() :param str myproxy_username: Myproxy username :param str myproxy_password: Myproxy password :param str myproxy_hostname: Myproxy hostname """ from myproxy.client import MyProxyClient myproxy_cert_location = config.get('DEFAULT', 'hessian_service_certfile') # try to get the myproxy info from ini file if not specified if not myproxy_hostname: myproxy_hostname = get_myproxy_value_from_config(config, 'hostname') if not myproxy_username: myproxy_username = get_myproxy_value_from_config(config, 'username') if not myproxy_password: myproxy_password = get_myproxy_value_from_config(config, 'password') myproxy_dir = os.path.dirname(myproxy_cert_location) myproxy_certs_dir = os.path.join(myproxy_dir, 'certificates') if not os.path.isdir(myproxy_dir): os.mkdir(myproxy_dir) if not os.path.isdir(myproxy_certs_dir): os.mkdir(myproxy_certs_dir) if myproxy_hostname is None: print '\nEnter myproxy hostname:', myproxy_hostname = raw_input() if myproxy_username is None: print 'Enter myproxy username:'******'Enter password for %s: ' % myproxy_username) myproxy = MyProxyClient(hostname=myproxy_hostname, caCertDir=myproxy_certs_dir) credentials = myproxy.logon(myproxy_username, myproxy_password, bootstrap=True, lifetime=259200) myproxy.writeProxyFile(credentials[0], credentials[1], credentials[2], filePath=myproxy_cert_location)
def renew_certificate(host, port, username, password): sdlog.info("SDMYPROX-002", "Renew certificate..") # we need a mkdir here to prevent 'No such file or directory' myproxyclient error (see TAGFERE5435 for more info) sd = sdconfig.get_security_dir() if not os.path.isdir(sd): os.makedirs(sd) # currently, we set bootstrap option everytime # # TODO: change this to set only the first time (i.e. if .esg/certificates is empty) # bootstrap = True # currently, we set trustroots option everytime updateTrustRoots = True authnGetTrustRootsCall = False # TODO: maybe add option in 'synda certificate' to use specify another path for cadir (for debugging purpose) #ROOT_TRUSTROOT_DIR = '/etc/grid-security/certificates' #USER_TRUSTROOT_DIR = '~/.globus/certificates' # set env. os.environ['ESGF_CREDENTIAL'] = sdconfig.esgf_x509_proxy os.environ['ESGF_CERT_DIR'] = sdconfig.esgf_x509_cert_dir os.environ['X509_CERT_DIR'] = sdconfig.esgf_x509_cert_dir if 'X509_USER_PROXY' in os.environ: del os.environ['X509_USER_PROXY'] #if 'GLOBUS_LOCATION' in os.environ: # del os.environ['GLOBUS_LOCATION'] # main myproxy_clnt = MyProxyClient(hostname=host, port=port, caCertDir=sdconfig.esgf_x509_cert_dir, proxyCertLifetime=43200) # 12 hours # credname=credname creds = myproxy_clnt.logon(username, password, bootstrap=bootstrap, updateTrustRoots=updateTrustRoots, authnGetTrustRootsCall=authnGetTrustRootsCall) # store cert on disk fout = open(sdconfig.esgf_x509_proxy, 'w') for cred in creds: fout.write(cred) fout.close()
def login_mpc(request): try: common.authentication_required(request) form = forms.MPCForm(request.POST) data = common.validate_form(form, ('username', 'password')) logger.info('Authenticating MyProxyClient for {}'.format( data['username'])) services = openid.services(request.user.auth.openid_url, (URN_MPC, )) g = re.match('socket://(.*):(.*)', services[0].server_url) if g is None or len(g.groups()) != 2: raise MPCEndpointParseError() host, port = g.groups() from OpenSSL import SSL MyProxyClient.SSL_METHOD = SSL.TLSv1_2_METHOD try: m = MyProxyClient(hostname=host, caCertDir=settings.WPS_CA_PATH) c = m.logon(data['username'], data['password'], bootstrap=True) except Exception as e: raise common.AuthenticationError(user=data['username']) logger.info( 'Authenticated with MyProxyClient backend for user {}'.format( data['username'])) request.user.auth.update('myproxyclient', c) except WPSError as e: logger.exception('Error authenticating MyProxyClient') return common.failed(str(e)) else: metrics.track_login(metrics.WPS_MPC_LOGIN_SUCCESS, request.user.auth.openid_url) return common.success({ 'type': request.user.auth.type, 'api_key': request.user.auth.api_key }) finally: if not request.user.is_anonymous: metrics.track_login(metrics.WPS_MPC_LOGIN, request.user.auth.openid_url)
def setUp(self): super(MyProxyClientLiveTestCase, self).setUp() configParser = CaseSensitiveConfigParser() configFilePath = path.join(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], MyProxyClientLiveTestCase.CONFIG_FILENAME) configParser.read(configFilePath) self.cfg = {} for section in configParser.sections(): self.cfg[section] = dict(configParser.items(section)) configFilePath = path.expandvars(self.cfg['setUp']['cfgFilePath']) self.clnt = MyProxyClient(cfgFilePath=configFilePath) # Get trust roots bootstrapping trust ready for test self.trustRoots = self.clnt.getTrustRoots(writeToCACertDir=True, bootstrap=True) # Keep a copy of files stored ready for tearDown tidy up self.trustRootFiles = [] dirContents = os.listdir(self.clnt.caCertDir) for fileName in self.trustRoots: self.assert_(fileName in dirContents) file_path = os.path.join(self.clnt.caCertDir, fileName) self.trustRootFiles.append(file_path)
def main(argv=sys.argv): op = make_optparser() logname = os.environ.get('LOGNAME') nArgs = len(argv) if nArgs < 2: op.error('No command set') else: command = argv[1] # Catch example of just specifying --help or '-h' if command in ['--help', '-h']: argl = argv[1:2] command = None elif command != 'logon': op.error('Command %s not supported' % command) elif nArgs < 3: op.error('No command options set') else: argl = argv[2:] options = op.parse_args(argl)[0] if options.outfile is None: if MyProxyClient.X509_USER_PROXY_ENVVARNAME in os.environ: options.outfile = os.environ[ MyProxyClient.X509_USER_PROXY_ENVVARNAME] else: op.error("Credential output file must be specified or %r set" % MyProxyClient.X509_USER_PROXY_ENVVARNAME) if options.username is None: options.username = logname if options.cadir: cadir = options.cadir elif MyProxyClient.X509_CERT_DIR_ENVVARNAME in os.environ: cadir = os.environ[MyProxyClient.X509_CERT_DIR_ENVVARNAME] elif logname == 'root': cadir = MyProxyClient.ROOT_TRUSTROOT_DIR else: cadir = os.path.join( os.path.expanduser(MyProxyClient.USER_TRUSTROOT_DIR)) client_props = dict( caCertDir=cadir, hostname=options.hostname, port=options.port, proxyCertLifetime=options.lifetime, ) myproxy = MyProxyClient(**client_props) do_logon(myproxy, options)
def remove_credential(JObject): # username = JObject['watts_userid'] username = JObject['cred_state'] ConfParams = JObject['conf_params'] # MYPROXY_SERVER_PWD = ConfParams['myproxy_server_pwd'] MYPROXY_CERT = ConfParams['myproxy_cert'] MYPROXY_KEY = ConfParams['myproxy_key'] MYPROXY_SERVER = ConfParams['myproxy_server'] MYPROXY_SERVER_DN = ConfParams['myproxy_server_dn'] REMOVE_CERTIFICATE = bool(ConfParams['remove_certificate']) if not MYPROXY_SERVER_DN: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, CACertDir="/etc/grid-security/certificates") else: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, serverDN = MYPROXY_SERVER_DN, CACertDir="/etc/grid-security/certificates") # check if credential exists if REMOVE_CERTIFICATE: info = myproxy_clnt.info(username, sslCertFile = MYPROXY_CERT, sslKeyFile = MYPROXY_KEY) # time.sleep(3) if info[0]: myproxy_clnt.destroy(username, sslCertFile=MYPROXY_CERT, sslKeyFile=MYPROXY_KEY) return json.dumps({'result': 'ok'})
def __init__(self, port, hostname, serverDN, proxyCertMaxLifetime=None, proxyCertLifetime=None): self._client = MyProxyClient() self._client.port = port self._client.hostname = hostname self._client.serverDN = serverDN if proxyCertMaxLifetime: self._client.proxyCertMaxLifetime = proxyCertMaxLifetime if proxyCertLifetime: self._client.proxyCertLifetime = proxyCertLifetime
def logon(self, username=None, password=None, hostname=None, bootstrap=False, update_trustroots=True, interactive=True): """ Obtain ESGF credentials from the specified MyProxy service. If ``interactive == True`` then any missing parameters of ``password``, ``username`` or ``hostname`` will be prompted for at the terminal. :param interactive: Whether to ask for input at the terminal for any missing information. I.e. username, password or hostname. :param bootstrap: Whether to bootstrap the trustroots for this MyProxy service. :param update_trustroots: Whether to update the trustroots for this MyProxy service. """ if interactive: if hostname is None: print 'Enter myproxy hostname:', hostname = raw_input() if username is None: print 'Enter myproxy username:'******'Enter password for %s: ' % username) if None in (hostname, username, password): raise OpenidResolutionError('Full logon details not available') c = MyProxyClient(hostname=hostname, caCertDir=self.esgf_certs_dir) creds = c.logon(username, password, bootstrap=bootstrap, updateTrustRoots=update_trustroots) with open(self.esgf_credentials, 'w') as fh: for cred in creds: fh.write(cred)
def store_credential(JObject, usercert, userkey): username = JObject['watts_userid'] ConfParams = JObject['conf_params'] prefix = ConfParams['prefix'] username = prefix + '_' + username MYPROXY_SERVER_PWD_KEY_ID = ConfParams['myproxy_server_pwd_key_id'] MYPROXY_CERT = ConfParams['myproxy_cert'] MYPROXY_KEY = ConfParams['myproxy_key'] PROXY_LIFETIME = int(ConfParams['proxy_lifetime']) MYPROXY_SERVER = ConfParams['myproxy_server'] MYPROXY_SERVER_DN = ConfParams['myproxy_server_dn'] if not MYPROXY_SERVER_DN: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, CACertDir="/etc/grid-security/certificates") else: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, serverDN = MYPROXY_SERVER_DN, CACertDir="/etc/grid-security/certificates") MYPROXY_SERVER_PWD = get_secret_from_passwordd(MYPROXY_SERVER_PWD_KEY_ID) myproxy_clnt.store(username = username, passphrase = MYPROXY_SERVER_PWD, certFile = usercert, keyFile = userkey, sslCertFile = MYPROXY_CERT, sslKeyFile = MYPROXY_KEY, sslKeyFilePhassphrase = None, lifetime = PROXY_LIFETIME, force = True) return 0
class MyProxyController(object): def __init__(self, port, hostname, serverDN, proxyCertMaxLifetime=None, proxyCertLifetime=None): self._client = MyProxyClient() self._client.port = port self._client.hostname = hostname self._client.serverDN = serverDN if proxyCertMaxLifetime: self._client.proxyCertMaxLifetime = proxyCertMaxLifetime if proxyCertLifetime: self._client.proxyCertLifetime = proxyCertLifetime def login(self, username, password, certPath, vdtLocation=None): proxyFileName = self.formProxyFileName(username, certPath) if not username or len(username) == 0: raise ValueError("invalid username") if not password or len(password) == 0: raise ValueError("invalid username") else: logger.info("myproxy logon with username: %s", username) if vdtLocation: context = { "username": username, "serverDN": self._client.serverDN, "hostname": self._client.hostname, "password": password, "proxyFileName": proxyFileName, "certPath": certPath, "vdtLocation": vdtLocation, } command = """ . ${vdtLocation}/setup.sh && \ echo ${password} | \ MYPROXY_SERVER_DN='${serverDN}' \ myproxy-get-delegation \ --pshost ${hostname} \ --username ${username} \ --stdin_pass \ --out ${proxyFileName} >> ${certPath}/../logs/myproxy.log 2>&1 """ os.system(Template(command).substitute(context)) else: proxy = self._client.logon(username=username, passphrase=password) logger.info( "writing proxy certificate retrieved from myproxy for user [%s] at [%s]", username, certPath ) if not os.path.exists(certPath): os.makedirs(certPath) GraysonUtil.writeFile(outputPath=proxyFileName, data=proxy[0]) def formProxyFileName(self, username, certPath): return os.path.join(certPath, "x509_proxy_%s" % username)
def test03_ssl_verification(self): # SSL verification callback # Ensure no relevant environment variables are set which might affect # the result try: serverDN = os.environ.get( MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME) if serverDN is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME] serverName = os.environ.get( MyProxyClient.MYPROXY_SERVER_ENVVARNAME) if serverName is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_ENVVARNAME] client = MyProxyClient() connection = None errorStatus = False successStatus = True errorDepth = 0 valid_peer_cert_str = open(self.__class__.HOSTCERT_FILEPATH).read() valid_peer_cert = crypto.load_certificate(crypto.FILETYPE_PEM, valid_peer_cert_str) # This would normally be called implicitly during the SSL handshake status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) expired_peer_cert_str = open( self.__class__.EXPIREDCERT_FILEPATH).read() expired_peer_cert = crypto.load_certificate( crypto.FILETYPE_PEM, expired_peer_cert_str) # Match based on full DN instead - this takes precedence over # hostname match client.serverDN = self.__class__.HOSTCERT_DN status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) # Check for expired certificate status = client.ssl_verification(connection, expired_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == errorStatus) finally: if serverDN is not None: os.environ[ MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME] = serverDN if serverName is not None: os.environ[ MyProxyClient.MYPROXY_SERVER_ENVVARNAME] = serverName
def logon(self, username=None, password=None, hostname=None, bootstrap=False, update_trustroots=True, interactive=True): """ Obtain ESGF credentials from the specified MyProxy service. If ``interactive == True`` then any missing parameters of ``password``, ``username`` or ``hostname`` will be prompted for at the terminal. :param interactive: Whether to ask for input at the terminal for any missing information. I.e. username, password or hostname. :param bootstrap: Whether to bootstrap the trustroots for this MyProxy service. :param update_trustroots: Whether to update the trustroots for this MyProxy service. """ if interactive: if hostname is None: print('Enter myproxy hostname:'), hostname = input() if username is None: print('Enter myproxy username:'******'Enter password for %s: ' % username) if None in (hostname, username, password): raise OpenidResolutionError('Full logon details not available') c = MyProxyClient(hostname=hostname, caCertDir=self.esgf_certs_dir) creds = c.logon(username, password, bootstrap=bootstrap, updateTrustRoots=update_trustroots) with open(self.esgf_credentials, 'wb') as fh: for cred in creds: fh.write(cred)
class MyProxyUtils(object): def __init__(self): self.config = config.read_config() self.cacertdir = os.path.expanduser("~/.esg/certificates") self.credsfile = os.path.expanduser("~/.esg/credentials.pem") self.myproxy = MyProxyClient(hostname=self.config['nodes']['idp_node']) self.myproxy._setCACertDir(self.cacertdir) def get_trustroots(self): # Get trust roots self.trustRoots = self.myproxy.getTrustRoots(self.config['account']['username'], self.config['account']['password'], writeToCACertDir=True, bootstrap=True) def get_credentials(self): # Get credentials (and trustroots) self.credentials = self.myproxy.logon(self.config['account']['username'], self.config['account']['password']) # Write Credentials with open(self.credsfile, 'w') as f: f.write(self.credentials[0]+self.credentials[1]) os.chmod(self.credsfile, self.myproxy.PROXY_FILE_PERMISSIONS) def delete_credentials(self): # Delete credentials file if os.path.exists(self.credsfile): os.remove(self.credsfile) def delete_trustroots(self): # Delete trustroots and cacert directory if os.path.exists(self.cacertdir): shutil.rmtree(self.cacertdir)
def test01EnvironmentVarsSet(self): try: environBackup = os.environ.copy() os.environ['MYPROXY_SERVER'] = 'localhost.domain' os.environ['MYPROXY_SERVER_DN'] = '/O=NDG/OU=Raphael/CN=raphael' os.environ['MYPROXY_SERVER_PORT'] = '20000' client = MyProxyClient(openSSLConfFilePath=mkPath('openssl.conf'), proxyCertMaxLifetime=60000, proxyCertLifetime=30000, caCertDir=mkPath('')) self.assertTrue(client.port == 20000) self.assertTrue(client.hostname == 'localhost.domain') self.assertTrue(client.serverDN == '/O=NDG/OU=Raphael/CN=raphael') self.assertTrue(client.proxyCertMaxLifetime == 60000) self.assertTrue(client.proxyCertLifetime == 30000) self.assertTrue( client.openSSLConfFilePath == mkPath('openssl.conf')) self.assertTrue(client.caCertDir == mkPath('')) finally: os.environ = environBackup
def initialise(self, app_conf, prefix=DEFAULT_PARAM_PREFIX, myProxyClientPrefix=MYPROXY_CLIENT_PARAM_PREFIX, **local_conf): """Parse dictionary of configuration items updating the relevant attributes of this instance @type prefix: basestring @param prefix: prefix for configuration items @type myProxyClientPrefix: basestring @param myProxyClientPrefix: explicit prefix for MyProxyClient class specific configuration items @type app_conf: dict @param app_conf: PasteDeploy application specific configuration dictionary """ super(MyProxyProvisionedSessionMiddleware, self).initialise(app_conf, prefix=prefix, **local_conf) # Sanity check if not isinstance(prefix, basestring): prefix = '' # Get MyProxyClient initialisation parameters myProxyClientFullPrefix = prefix + myProxyClientPrefix myProxyClientKw = dict([(k.replace(myProxyClientFullPrefix, ''), v) for k,v in app_conf.items() if k.startswith(myProxyClientFullPrefix)]) self.myProxyClient = MyProxyClient(**myProxyClientKw) for k in local_conf: paramName = k.replace(prefix, '', 1) if paramName in self.__class__.PARAM_NAMES: setattr(self, paramName, local_conf[k])
a = AES.new(session_key) plaintext = a.decrypt(unhexlify(slcsResp)) # remove AES padding n = ord(plaintext[-1]) # last byte contains number of padding bytes if n > AES.block_size or n > len(plaintext): raise Exception('invalid padding') print plaintext try: certificate = slcs_handler(StringIO(plaintext[:-n])) print "cert = " + str(certificate) except SLCSException, e: # TODO add error handling print "Exception: " + str(e) pass #return template(simple_page,title='Error - %s' % e.expression, body='<h1>%s</h1><pre>%s</pre>' % (e.expression, e.message)) username = certificate.get_dn() passphrase = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(8)) # Create a passphrase of length = 8 data = get_base_data(context, request) data['username'] = username data['passphrase'] = passphrase c = MyProxyClient(hostname='myproxy2.arcs.org.au', port= 7512, serverDN='/C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au') c.put(username, passphrase, certificate, certificate.get_key()._key, lambda *a: '', retrievers='*') print "MYPROXY Username = "******"MYPROXY Passphrase = " + passphrase print "URL = " + originURL return data
from arcs.gsi.certificate import Certificate certFile = open('cert.pem', 'r') keyFile = open('cert.key', 'r') certString = certFile.read() keyString = keyFile.read() print certString print keyString certificate = Certificate(str(certString), str(keyString)) #certificate.add_extension({'name' : 'Proxy Cert Info', 'critical' : 1, 'value' : 'Path Length Constraint: infinite, Policy Language: Inherit all'}) #print certificate c = MyProxyClient(hostname='myproxy2.arcs.org.au', port= 7512, serverDN='/C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au') #c = MyProxyClient(hostname='myproxydev.arcs.org.au', serverDN='/C=AU/O=APACGrid/OU=VPAC/CN=myproxydev.arcs.org.au') #c.put('testProxy', 'pa55w0rd', certificate, certificate.get_key()._key, \ #lambda *a: '', ownerCertFile=certificate, ownerKeyFile=certificate.get_key()._key, ownerPassphraseCallback=lambda *a: '', \ #retrievers='*') #print "Trying to put:" #print certificate.get_key() #c.put('testuser50', 'askldasdhqwod', certificate, certificate.get_key()._key, \ # lambda *a: '', retrievers='*') #print "Got here" success, err, field = c.info('asdasdas') if success: print "IT WORKED" else: print ":("
class MyProxyClientLiveTestCase(_MyProxyClientTestCase): '''Tests require a connection to a real MyProxy service running on a host. The server must be set up as a credential repository - i.e. able to receive and store credentials ''' CONFIG_FILENAME = "myProxyClientTest.cfg" def setUp(self): super(MyProxyClientLiveTestCase, self).setUp() configParser = CaseSensitiveConfigParser() configFilePath = path.join(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], MyProxyClientLiveTestCase.CONFIG_FILENAME) configParser.read(configFilePath) self.cfg = {} for section in configParser.sections(): self.cfg[section] = dict(configParser.items(section)) configFilePath = path.expandvars(self.cfg['setUp']['cfgFilePath']) self.clnt = MyProxyClient(cfgFilePath=configFilePath) # Get trust roots bootstrapping trust ready for test self.trustRoots = self.clnt.getTrustRoots(writeToCACertDir=True, bootstrap=True) # Keep a copy of files stored ready for tearDown tidy up self.trustRootFiles = [] dirContents = os.listdir(self.clnt.caCertDir) for fileName in self.trustRoots: self.assertTrue(fileName in dirContents) file_path = os.path.join(self.clnt.caCertDir, fileName) self.trustRootFiles.append(file_path) def tearDown(self): """Clear up CA certs retrieved in test01GetTrustRoots call ready for next run of these unit tests """ self.trustRoots = None self._deleteTrustRootFiles() def _deleteTrustRootFiles(self): """Helper method clears up CA certs in trust roots directory set from previous call to test01GetTrustRoots() """ for fileName in self.trustRootFiles: os.remove(fileName) def test01GetTrustRoots(self): # Test output from getTrustRoots call made in setUp self.assertTrue(self.trustRoots) self.assertTrue(isinstance(self.trustRoots, dict)) self.assertTrue(len(self.trustRoots) > 0) for fileName, fileContents in list(self.trustRoots.items()): if fileName.endswith('.0'): # test parsing certificate cert = crypto.load_certificate(crypto.FILETYPE_PEM, fileContents) self.assertTrue(cert) self.assertTrue(isinstance(cert, crypto.X509)) subj = cert.get_subject() self.assertTrue(subj) print(("Trust root certificate retrieved with DN=%s" % subj)) def test02Store(self): # Test get trust root to bootstrap trust self.test01GetTrustRoots() # upload X509 cert and private key to repository thisSection = self.cfg['test02Store'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("\ntest02Store credential pass-phrase: ") sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest02Store credential owner " "pass-phrase: ") certFile = path.expandvars(thisSection['ownerCertFile']) keyFile = path.expandvars(thisSection['ownerKeyFile']) sslCertFile = path.expandvars(thisSection['sslCertFile']) sslKeyFile = path.expandvars(thisSection['sslKeyFile']) self.clnt.store(thisSection['username'], passphrase, certFile, keyFile, sslCertFile=sslCertFile, sslKeyFile=sslKeyFile, sslKeyFilePassphrase=sslKeyFilePassphrase, force=False) print(("Store creds for user %s" % thisSection['username'])) def test03GetDelegation(self): # retrieve proxy cert./private key thisSection = self.cfg['test03GetDelegation'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("\ntest03GetDelegation passphrase: ") proxyCertFile = path.expandvars(thisSection['proxyCertFileOut']) proxyKeyFile = path.expandvars(thisSection['proxyKeyFileOut']) creds = self.clnt.getDelegation(thisSection['username'], passphrase) print("proxy credentials:") print(b''.join(creds)) with open(proxyCertFile, 'wb') as proxy_cert_file: proxy_cert_file.write(creds[0] + b''.join(creds[2:])) with open(proxyKeyFile, 'wb') as proxy_key_file: proxy_key_file.write(creds[1]) def test04Info(self): # Retrieve information about a given credential thisSection = self.cfg['test04Info'] # sslKeyFilePassphrase can be omitted from the congif file in which case # the get call below would return None sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest04Info owner credentials " "passphrase: ") credExists, errorTxt, fields = self.clnt.info( thisSection['username'], path.expandvars(thisSection['sslCertFile']), path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print("test04Info... ") print("credExists: %s" % credExists) print("errorTxt: " + errorTxt) print("fields: %s" % fields) def test06ChangePassphrase(self): # change pass-phrase protecting a given credential thisSection = self.cfg['test06ChangePassphrase'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("test06ChangePassphrase - passphrase: ") newPassphrase = thisSection.get('newPassphrase') if newPassphrase is None: newPassphrase = getpass( "test06ChangePassphrase - new passphrase: ") confirmNewPassphrase = getpass("test06ChangePassphrase - confirm " "new passphrase: ") if newPassphrase != confirmNewPassphrase: self.fail("New and confirmed new password don't match") sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') or \ passphrase self.clnt.changePassphrase(thisSection['username'], passphrase, newPassphrase, path.expandvars(thisSection['sslCertFile']), path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print("Changed pass-phrase") def test05GetDelegationWithBootstrappedTrustRoots(self): # Get delegation call whilst simulataneously bootstrapping trust roots thisSection = self.cfg['test05GetDelegationWithBootstrappedTrustRoots'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass( "\n" "test05GetDelegationWithBootstrappedTrustRoots" "passphrase: ") # Ensure any previously set trust root files are removed self._deleteTrustRootFiles() creds = self.clnt.getDelegation(thisSection['username'], passphrase, bootstrap=True) print("proxy credentials:") print(b''.join(creds)) def test07Destroy(self): # destroy credentials for a given user thisSection = self.cfg['test07Destroy'] sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest07Destroy credential owner " "passphrase: ") self.clnt.destroy( thisSection['username'], sslCertFile=path.expandvars(thisSection['sslCertFile']), sslKeyFile=path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print(("Destroy creds for user %s" % thisSection['username']))
myproxyserver = None myproxyuser = None myproxypass = None with open(auth_file) as fa: lines = fa.readlines() for line in lines: if len(line) > 0 and not line.startswith("#"): line = line.strip() if line.find("myproxyserver = ") != -1: proxy_found = True tokens = line.split(";") for token in tokens: key_value = token.split(" = ") value = key_value[1].strip().replace("\\n", "\n") key = key_value[0].strip() if key == "myproxyserver": myproxyserver = value elif key == "myproxyuser": myproxyuser = value elif key == "myproxypass": myproxypass = value if myproxyserver and myproxyuser and myproxypass: from myproxy.client import MyProxyClient myproxy = MyProxyClient(hostname=myproxyserver, caCertDir=cadir) credentials = myproxy.logon(myproxyuser, myproxypass) with open(proxy_file, "w") as fp: for cred in credentials: fp.write(cred)
myproxyserver = None myproxyuser = None myproxypass = None with open(auth_file) as fa: lines = fa.readlines() for line in lines: if len(line) > 0 and not line.startswith("#"): line = line.strip() if line.find("myproxyserver = ") != -1: proxy_found = True tokens = line.split(";") for token in tokens: key_value = token.split(" = ") value = key_value[1].strip().replace("\\n","\n") key = key_value[0].strip() if key == "myproxyserver": myproxyserver = value elif key == "myproxyuser": myproxyuser = value elif key == "myproxypass": myproxypass = value if myproxyserver and myproxyuser and myproxypass: from myproxy.client import MyProxyClient myproxy = MyProxyClient(hostname=myproxyserver, caCertDir=cadir) credentials = myproxy.logon(myproxyuser, myproxypass) with open(proxy_file, "w") as fp: for cred in credentials: fp.write(cred)
def __init__(self): self.config = config.read_config() self.cacertdir = os.path.expanduser("~/.esg/certificates") self.credsfile = os.path.expanduser("~/.esg/credentials.pem") self.myproxy = MyProxyClient(hostname=self.config['nodes']['idp_node']) self.myproxy._setCACertDir(self.cacertdir)
def process_slcs_token(context, request): """ Creates a SLCS certificate based on a shibboleth auth_token, request and url. Uploads SLCS certificate to specified MyProxy. If no such MyProxy exists, creates one with specified details before uploading. @param request: Data submitted via https POST. @requires request: 6 parameters 'auth_token' Shibboleth authentication token as text 'dn' DN string of request 'reqURL' URL of SLCS server 'myproxy_username' Desired MyProxy username 'myproxy_passphrase' Desired MyProxy passphrase 'elements' Any extensions to be applied to the certificate NOTE: Must be in the the form of: [{'name' : <String>, 'critical' : 0=true 1=false, 'value' : <String>}, ..., ...] An example request is below... dn: DC=slcs,DC=bestgrid,DC=org,DC=nz,O=Organisation Name,CN=Contact Name rDJ6f5h1bqDAQ-tKnQx68LWsOjk elements: [{'critical': False, 'name': 'ExtendedKeyUsage', 'value': 'ClientAuth'}, {'critical': True, 'name': 'KeyUsage', 'value': 'DigitalSignature,KeyEncipherment'}, {'critical': False, 'name': 'CertificatePolicies', 'value': '1.3.6.1.4.1.31863.1.0.1'}, {'critical': False, 'name': 'SubjectAltName', 'value': 'email:[email protected]'}] auth_token: 4F24CEA27F23A47927D92CA89D7F9756E89689A8968CDBB907A8611FB232A768 myproxy_username: testuser myproxy_passphrase: pa55w0rd reqURL: https://slcs1.arcs.org.au:443/SLCS/certificate """ post_data = request.POST if (post_data.has_key("auth_token") and post_data.has_key("dn") and \ post_data.has_key("reqURL") and post_data.has_key("elements") and \ post_data.has_key("myproxy_username") and post_data.has_key("myproxy_passphrase")): elements = eval(post_data['elements']) certreq = CertificateRequest(dn=str(post_data['dn']), extensions=elements) certreq.sign() data = urlencode({'AuthorizationToken': str(post_data['auth_token']), 'CertificateSigningRequest': repr(certreq)}) print "token:\n"+str(post_data['auth_token']) print "CertSigningRequest:\n"+repr(certreq) certResp = urllib2.urlopen(post_data['reqURL'], data) dom = xml.dom.minidom.parse(certResp) status = dom.getElementsByTagName("Status")[0].childNodes[0].data if status == 'Error': error = dom.getElementsByTagName("Error")[0].childNodes[0].data stack = dom.getElementsByTagName("StackTrace")[0].childNodes[0].data print stack print error #raise SLCSException(error, stack) cert = ''.join([i.data for i in dom.getElementsByTagName("Certificate")[0].childNodes]) certificate = Certificate(str(cert), certreq.get_key()) certFile = open('cert.pem', 'w') certFile.writelines(repr(certificate)) certFile.close() keyFile = open('cert.key', 'w') keyFile.writelines(str(certificate.get_key())) keyFile.close() username = str(post_data['myproxy_username']) passphrase = str(post_data['myproxy_passphrase']) #Upload to MyProxy... c = MyProxyClient(hostname='myproxy2.arcs.org.au', port= 7512, serverDN='/C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au') c.put(username, passphrase, certificate, certificate.get_key()._key, lambda *a: '', retrievers='*') not_before, not_after = certificate.get_times() return Response(str(not_before)+"\n"+str(not_after)) else: return Response("Incorrect parameters")
class MyProxyProvisionedSessionMiddleware(SSLCtxSessionMiddleware): """Provisions a session object with PKI credentials from a MyProxy server. Call MyProxy logon to populate a session based SSL context object with client PKI credentials to make SSL calls to other services. @cvar DEFAULT_CERT_EXPIRY_OFFSET: default time offset prior to certificate expiry used to trigger certificate renewal. e.g. if the offset is 1 day and the certificate will expiry within one day then certificate renewal is invoked with a fresh MyProxy logon call. @type DEFAULT_CERT_EXPIRY_OFFSET: timedelta """ __slots__ = ( '__myProxyClient', '__certExpiryOffset', '__myProxyClientSSLCertFile', '__myProxyClientSSLKeyFile', '__myProxyClientSSLKeyFilePassphrase' ) PARAM_NAMES = tuple([i[2:] for i in __slots__]) del i DEFAULT_ENVIRON_SESSION_KEYNAME = "ndg.security.session" DEFAULT_PARAM_PREFIX = 'myproxy_provision_session.' MYPROXY_CLIENT_PARAM_PREFIX = 'myproxy_client.' DEFAULT_CERT_EXPIRY_OFFSET = timedelta(days=1) def __init__(self, app): super(MyProxyProvisionedSessionMiddleware, self).__init__(app) self.__myProxyClient = MyProxyClient() self.__certExpiryOffset = self.__class__.DEFAULT_CERT_EXPIRY_OFFSET self.__myProxyClientSSLCertFile = None self.__myProxyClientSSLKeyFile = None self.__myProxyClientSSLKeyFilePassphrase = None @property def myProxyClient(self): '''MyProxy client used to make calls to MyProxy server to retrieve credentials for user ''' return self.__myProxyClient @myProxyClient.setter def myProxyClient(self, val): '''MyProxy client used to make calls to MyProxy server to retrieve credentials for user ''' if not isinstance(val, MyProxyClient): raise TypeError('Expecting %r type for "myProxyClient", got %r' % (MyProxyClient, type(val))) self.__myProxyClient = val @property def certExpiryOffset(self): '''Certificate expiry offset measured in seconds before current time ''' return self.__certExpiryOffset @certExpiryOffset.setter def certExpiryOffset(self, val): '''Certificate expiry offset measured in seconds before current time ''' if isinstance(val, basestring): self.__certExpiryOffset = timedelta(seconds=float(val)) elif isinstance(val, (float, int, long)): self.__certExpiryOffset = timedelta(seconds=val) elif isinstance(val, timedelta): self.__certExpiryOffset = val else: raise TypeError('Expecting string, int, long, float or timedelta ' 'type for "certExpiryOffset", got %r' % type(val)) @property def myProxyClientSSLCertFile(self): return self.__myProxyClientSSLCertFile @myProxyClientSSLCertFile.setter def myProxyClientSSLCertFile(self, val): if not isinstance(val, basestring): raise TypeError('Expecting string type for ' '"myProxyClientSSLCertFile"; got %r' % type(val)) if not os.access(val, os.R_OK): raise IOError('Error accessing "myProxyClientSSLCertFile" file %r' % val) self.__myProxyClientSSLCertFile = val @property def myProxyClientSSLKeyFile(self): return self.__myProxyClientSSLKeyFile @myProxyClientSSLKeyFile.setter def myProxyClientSSLKeyFile(self, val): if not isinstance(val, basestring): raise TypeError('Expecting string type for ' 'myProxyClientSSLKeyFile"; got %r' % type(val)) if not os.access(val, os.R_OK): raise IOError('Error accessing "myProxyClientSSLKeyFile" file %r' % val) self.__myProxyClientSSLKeyFile = val @property def myProxyClientSSLKeyFilePassphrase(self): return self.__myProxyClientSSLKeyFilePassphrase @myProxyClientSSLKeyFilePassphrase.setter def myProxyClientSSLKeyFilePassphrase(self, val): if not isinstance(val, basestring): raise TypeError('Expecting string type for ' 'myProxyClientSSLKeyFilePassphrase"; got %r' % type(val)) self.__myProxyClientSSLKeyFilePassphrase = val def initialise(self, app_conf, prefix=DEFAULT_PARAM_PREFIX, myProxyClientPrefix=MYPROXY_CLIENT_PARAM_PREFIX, **local_conf): """Parse dictionary of configuration items updating the relevant attributes of this instance @type prefix: basestring @param prefix: prefix for configuration items @type myProxyClientPrefix: basestring @param myProxyClientPrefix: explicit prefix for MyProxyClient class specific configuration items @type app_conf: dict @param app_conf: PasteDeploy application specific configuration dictionary """ super(MyProxyProvisionedSessionMiddleware, self).initialise(app_conf, prefix=prefix, **local_conf) # Sanity check if not isinstance(prefix, basestring): prefix = '' # Get MyProxyClient initialisation parameters myProxyClientFullPrefix = prefix + myProxyClientPrefix myProxyClientKw = dict([(k.replace(myProxyClientFullPrefix, ''), v) for k,v in app_conf.items() if k.startswith(myProxyClientFullPrefix)]) self.myProxyClient = MyProxyClient(**myProxyClientKw) for k in local_conf: paramName = k.replace(prefix, '', 1) if paramName in self.__class__.PARAM_NAMES: setattr(self, paramName, local_conf[k]) @classmethod def filter_app_factory(cls, app, app_conf, **kw): """Configure filter and associated SSL Context session middleware """ _app = cls(app) _app.initialise(app_conf, **kw) # Set SSL Context middleware upstream from this app _app = SSLCtxSessionMiddleware.filter_app_factory(_app, app_conf, **kw) return _app @wsgify def __call__(self, request): ''' @param request: WSGI request object @type request: WebOb.Request @return: WSGI response @rtype: iterable ''' resp = super(MyProxyProvisionedSessionMiddleware, self).__call__( request) session = self.getSession(request) # if not certificate has been set or if it is present but expired, # renew if (not self.__class__._is_cert_set(session) or self._is_cert_expired(session)): self._refresh_credentials(request) return resp def _getMyProxyLogonCallCreds(self, request): """Get credentials for MyProxy logon. Override to give custom behaviour @param request: WSGI request object @type request: WebOb.Request @rtype: tuple @return: two element tuple containing username and password to use with logon call to MyProxy. None is set by default for the case where the client authenticates over SSL with a client certificate. """ return (request.environ.get('REMOTE_USER'), None) def _refresh_credentials(self, request): """Refresh credentials by making a MyProxy server logon request""" username, password = self._getMyProxyLogonCallCreds(request) try: credentials = self.__myProxyClient.logon(username, password, sslCertFile=self.myProxyClientSSLCertFile, sslKeyFile=self.myProxyClientSSLKeyFile) except MyProxyClientError, e: raise httpexceptions.HTTPUnauthorized(str(e)) except socket.error, e: raise MyProxyRetrievalSocketError("Socket error with MyProxy " "server %r: %s" % (self.__myProxyClient.hostname,e))
def renew_certificate_NG(force,quiet=True): """Renew ESGF certificate.""" from myproxy.client import MyProxyClient myproxy_clnt = MyProxyClient(hostname="myproxy.somewhere.ac.uk") cert, private_key = myproxy_clnt.logon(username, password, bootstrap=True)
def put_credential(JObject, usercert, userkey): username = JObject['watts_userid'] ConfParams = JObject['conf_params'] prefix = ConfParams['prefix'] username = prefix + '_' + username plugin_base_dir = ConfParams['plugin_base_dir'] MYPROXY_SERVER_PWD_KEY_ID = ConfParams['myproxy_server_pwd_key_id'] MYPROXY_CERT = ConfParams['myproxy_cert'] MYPROXY_KEY = ConfParams['myproxy_key'] # PROXY_LIFETIME = int(ConfParams['proxy_lifetime']) MYPROXY_SERVER = ConfParams['myproxy_server'] MYPROXY_SERVER_DN = ConfParams['myproxy_server_dn'] if not MYPROXY_SERVER_DN: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, CACertDir="/etc/grid-security/certificates") else: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, serverDN = MYPROXY_SERVER_DN, CACertDir="/etc/grid-security/certificates") # get max lifetime for long-lived proxy cert = crypto.load_certificate(crypto.FILETYPE_PEM, usercert) notBefore = cert.get_notBefore() notAfter = cert.get_notAfter() notBefore = notBefore[:-1] notAfter = notAfter[:-1] notAfter_struct = time.strptime(notAfter, "%Y%m%d%H%M%S") notAfter_seconds = time.mktime(notAfter_struct) notBefore_struct = time.strptime(notBefore, "%Y%m%d%H%M%S") notBefore_seconds = time.mktime(notBefore_struct) MAX_LIFETIME = int(notAfter_seconds - notBefore_seconds - 24*3600) conn = myproxy_clnt._initConnection(certFile = MYPROXY_CERT, keyFile=MYPROXY_KEY) conn.connect((MYPROXY_SERVER, 7512)) # send globus compatibility stuff conn.write('0') # send store command - ensure conversion from unicode before writing ### Why is this not using myproxy_clnt instance, but the class??? logging.info('getting password for "%s" from passwordd' % MYPROXY_SERVER_PWD_KEY_ID) MYPROXY_SERVER_PWD = get_secret_from_passwordd(MYPROXY_SERVER_PWD_KEY_ID) logging.info(' => successs') logging.info('calling myproxy.put') cmd = MyProxyClient.PUT_CMD % (username, MYPROXY_SERVER_PWD, MAX_LIFETIME) logging.info('sent cmd to myproxy: %s' % str(cmd)) conn.write(str(cmd)) # process server response ### Why is this not using myproxy_clnt instance, but the class??? dat = conn.recv(MyProxyClient.SERVER_RESP_BLK_SIZE) logging.info('returned dat:: %s' % str(dat)) respCode, errorTxt = myproxy_clnt._deserializeResponse(dat) if respCode: raise MyProxyClientGetError("put_credential:1: %s (%s)" % (errorTxt, respCode)) dat = conn.recv(MyProxyClient.SERVER_RESP_BLK_SIZE) csr_reqst = crypto.load_certificate_request(crypto.FILETYPE_ASN1, dat) csr_reqst = crypto.dump_certificate_request(crypto.FILETYPE_PEM, csr_reqst) logging.info ('calling create_proxy') # logging.info ('csr_reqst: %s' % csr_reqst) # logging.info ('usercert: %s' % usercert) # logging.info ('userkey: %s' % userkey) # logging.info ('plugin_base_dir: %s' % plugin_base_dir) proxyCertTxt = create_proxy(csr_reqst, usercert, userkey, plugin_base_dir) # logging.info ('proxyCertTxt: "%s"' % proxyCertTxt) proxyCertTxt = crypto.load_certificate(crypto.FILETYPE_PEM, proxyCertTxt) proxyCertTxt = crypto.dump_certificate(crypto.FILETYPE_ASN1, proxyCertTxt) endCertTxt = usercert endCertTxt = crypto.load_certificate(crypto.FILETYPE_PEM, endCertTxt) endCertTxt = crypto.dump_certificate(crypto.FILETYPE_ASN1, endCertTxt) # now send the creds to myproxy-server # send_creds = str('1'+ proxyCertTxt + endCertTxt + rcauth_cert) send_creds = str('1'+ proxyCertTxt + endCertTxt) conn.send(send_creds) # process server response resp = conn.recv(MyProxyClient.SERVER_RESP_BLK_SIZE) respCode, errorTxt = myproxy_clnt._deserializeResponse(resp) if respCode: raise MyProxyClientGetError("put_credential:1: " + errorTxt) logging.info("put_credential successfully finished") return 0
def get_user_proxy(self, myproxy_server, userDN, force_remote=False): """Retrieve user proxy for the correct activity from myproxy and save it in memcache :param myproxy_server: myproxy server hostname :type myproxy_server: str :param userDN: user DN :type userDN: str :param force_remote: force retrieving from myproxy, defaults to False :param force_remote: bool, optional :return: user proxy :rtype: tuple """ cert = self.hostcert ckey = self.hostkey # Generate myproxy key key = sha1(userDN + "_" + self.cmsweb_endpoint).hexdigest() result_cache = REGION_SHORT.get(key) validity_h = 2 if isinstance(result_cache, NoValue) or force_remote: logging.info("Refresh user certificates for %s", userDN) else: logging.info( "User certificates from memcache. Checking validity...") try: certfile = tempfile.NamedTemporaryFile(delete=True) for crt in result_cache: certfile.write(crt) command = 'grid-proxy-info -f %s -e -h %s' % (certfile.name, validity_h) logging.debug('grid-proxy-info -f %s -e -h %s', certfile.name, validity_h) subprocess.check_call(command, shell=True) certfile.close() except subprocess.CalledProcessError as ex: certfile.close() if ex.returncode == 1: logging.warn("Credential timeleft < %sh", validity_h) else: logging.exception("Credential validity check failed") else: return result_cache logging.info( "myproxy_client = MyProxyClient(hostname='myproxy.cern.ch'") logging.info( "myproxy_client.logon('%s', None, sslCertFile='%s', sslKeyFile='%s')", key, cert, ckey) # Retrieve proxy myproxy_client = MyProxyClient(hostname=myproxy_server) try: cert = myproxy_client.logon(key, None, sslCertFile=cert, sslKeyFile=ckey) except MyProxyClientGetError: logging.error("MyProxy client exception during GET proxy") raise except MyProxyClientRetrieveError: logging.error("MyProxy client exception retrieving proxy") raise except gaierror: logging.error("Invalid myproxy url") raise except TypeError: logging.error("Invalid arguments provided for myproxy client") raise REGION_SHORT.set(key, cert) return cert
def get_credential(JObject): username = JObject['watts_userid'] AddLogins = JObject['additional_logins'] ConfParams = JObject['conf_params'] prefix = ConfParams['prefix'] username = prefix + '_' + username MYPROXY_SERVER_PWD_KEY_ID = ConfParams['myproxy_server_pwd_key_id'] MYPROXY_CERT = ConfParams['myproxy_cert'] MYPROXY_KEY = ConfParams['myproxy_key'] PROXY_LIFETIME = int(ConfParams['proxy_lifetime']) MYPROXY_SERVER = ConfParams['myproxy_server'] MYPROXY_SERVER_DN = ConfParams['myproxy_server_dn'] Provider = ConfParams['rcauth_op_entry'] if not MYPROXY_SERVER_DN: logging.info('this is the constructor:') logging.info('hostname: %s' % MYPROXY_SERVER) myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, CACertDir="/etc/grid-security/certificates") else: myproxy_clnt = MyProxyClient(hostname = MYPROXY_SERVER, serverDN = MYPROXY_SERVER_DN, CACertDir="/etc/grid-security/certificates") # check if credential exists logging.info('this is the info call:') logging.info('username: %s' % username) logging.info('sslCertFile: %s' % MYPROXY_CERT) logging.info('sslKeyFile: %s' % MYPROXY_KEY) info = myproxy_clnt.info(username, sslCertFile = MYPROXY_CERT, sslKeyFile = MYPROXY_KEY) logging.info('Just got this info from myproxy: "%s"' % str(info)) if info[0] == True and (info[2]['CRED_END_TIME'] <= int(time.time() + 12*60*60)): result = myproxy_clnt.destroy(username, sslCertFile = MYPROXY_CERT, sslKeyFile = MYPROXY_KEY) Msg ='Your certificate has expired, therefore it was removed. '+\ 'You will be redirected to login and verify your '+\ 'identity with RCauth to obtain a new one.' return json.dumps({'result':'oidc_login', 'provider': Provider, 'msg':Msg}) if info[0] == False and len(AddLogins) == 0: Msg ='Currently, we do not have a valid certificate for you. '+\ 'To obtain it, you will be redirected to login and verify your identity with RCauth.' return json.dumps({'result':'oidc_login', 'provider': Provider, 'msg':Msg}) if info[0] == False and len(AddLogins) != 0: try: req_and_store_cert(JObject) except Exception as E: UserMsg = 'Please logout and login again to request a new certificate from RCauth' logging.info = 'Request and store certificate failed with "%s"'%str(E) LogMsg = 'Request and store certificate failed with "%s"'%str(E) raise return json.dumps({'result':'error', 'user_msg':UserMsg, 'log_msg':LogMsg}) MYPROXY_SERVER_PWD = get_secret_from_passwordd(MYPROXY_SERVER_PWD_KEY_ID) logging.info ("calling 'myproxy.get'") result = myproxy_clnt.get(username=username, passphrase=MYPROXY_SERVER_PWD, lifetime = PROXY_LIFETIME, sslCertFile = MYPROXY_CERT, sslKeyFile = MYPROXY_KEY) # join all creds in a single file full_credential = ''.join([s for s in result]) Credential = [{'name':'Proxy certificate', 'type':'textfile', 'value':full_credential, 'rows':30, 'cols':64 , 'save_as': 'x509up_u1000'}] return json.dumps({'result':'ok', 'credential': Credential, 'state': username})
class MyProxyClientLiveTestCase(_MyProxyClientTestCase): '''Tests require a connection to a real MyProxy service running on a host. The server must be set up as a credential repository - i.e. able to receive and store credentials ''' CONFIG_FILENAME = "myProxyClientTest.cfg" def setUp(self): super(MyProxyClientLiveTestCase, self).setUp() configParser = CaseSensitiveConfigParser() configFilePath = path.join(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], MyProxyClientLiveTestCase.CONFIG_FILENAME) configParser.read(configFilePath) self.cfg = {} for section in configParser.sections(): self.cfg[section] = dict(configParser.items(section)) configFilePath = path.expandvars(self.cfg['setUp']['cfgFilePath']) self.clnt = MyProxyClient(cfgFilePath=configFilePath) # Get trust roots bootstrapping trust ready for test self.trustRoots = self.clnt.getTrustRoots(writeToCACertDir=True, bootstrap=True) # Keep a copy of files stored ready for tearDown tidy up self.trustRootFiles = [] dirContents = os.listdir(self.clnt.caCertDir) for fileName in self.trustRoots: self.assert_(fileName in dirContents) file_path = os.path.join(self.clnt.caCertDir, fileName) self.trustRootFiles.append(file_path) def tearDown(self): """Clear up CA certs retrieved in test01GetTrustRoots call ready for next run of these unit tests """ self.trustRoots = None self._deleteTrustRootFiles() def _deleteTrustRootFiles(self): """Helper method clears up CA certs in trust roots directory set from previous call to test01GetTrustRoots() """ for fileName in self.trustRootFiles: os.remove(fileName) def test01GetTrustRoots(self): # Test output from getTrustRoots call made in setUp self.assert_(self.trustRoots) self.assert_(isinstance(self.trustRoots, dict)) self.assert_(len(self.trustRoots) > 0) for fileName, fileContents in self.trustRoots.items(): if fileName.endswith('.0'): # test parsing certificate cert = crypto.load_certificate(crypto.FILETYPE_PEM, fileContents) self.assert_(cert) self.assert_(isinstance(cert, crypto.X509)) subj = cert.get_subject() self.assert_(subj) print("Trust root certificate retrieved with DN=%s" % subj) def test02Store(self): # Test get trust root to bootstrap trust self.test01GetTrustRoots() # upload X509 cert and private key to repository thisSection = self.cfg['test02Store'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("\ntest02Store credential pass-phrase: ") sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest02Store credential owner " "pass-phrase: ") certFile = path.expandvars(thisSection['ownerCertFile']) keyFile = path.expandvars(thisSection['ownerKeyFile']) sslCertFile = path.expandvars(thisSection['sslCertFile']) sslKeyFile = path.expandvars(thisSection['sslKeyFile']) self.clnt.store(thisSection['username'], passphrase, certFile, keyFile, sslCertFile=sslCertFile, sslKeyFile=sslKeyFile, sslKeyFilePassphrase=sslKeyFilePassphrase, force=False) print("Store creds for user %s" % thisSection['username']) def test03GetDelegation(self): # retrieve proxy cert./private key thisSection = self.cfg['test03GetDelegation'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("\ntest03GetDelegation passphrase: ") proxyCertFile = path.expandvars(thisSection['proxyCertFileOut']) proxyKeyFile = path.expandvars(thisSection['proxyKeyFileOut']) creds = self.clnt.getDelegation(thisSection['username'], passphrase) print "proxy credentials:" print ''.join(creds) open(proxyCertFile, 'w').write(creds[0]+''.join(creds[2:])) open(proxyKeyFile, 'w').write(creds[1]) def test04Info(self): # Retrieve information about a given credential thisSection = self.cfg['test04Info'] # sslKeyFilePassphrase can be omitted from the congif file in which case # the get call below would return None sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest04Info owner credentials " "passphrase: ") credExists, errorTxt, fields = self.clnt.info( thisSection['username'], path.expandvars(thisSection['sslCertFile']), path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print "test04Info... " print "credExists: %s" % credExists print "errorTxt: " + errorTxt print "fields: %s" % fields def test06ChangePassphrase(self): # change pass-phrase protecting a given credential thisSection = self.cfg['test06ChangePassphrase'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("test06ChangePassphrase - passphrase: ") newPassphrase = thisSection.get('newPassphrase') if newPassphrase is None: newPassphrase = getpass("test06ChangePassphrase - new passphrase: ") confirmNewPassphrase = getpass("test06ChangePassphrase - confirm " "new passphrase: ") if newPassphrase != confirmNewPassphrase: self.fail("New and confirmed new password don't match") sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') or \ passphrase self.clnt.changePassphrase(thisSection['username'], passphrase, newPassphrase, path.expandvars(thisSection['sslCertFile']), path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print("Changed pass-phrase") def test05GetDelegationWithBootstrappedTrustRoots(self): # Get delegation call whilst simulataneously bootstrapping trust roots thisSection = self.cfg['test05GetDelegationWithBootstrappedTrustRoots'] passphrase = thisSection.get('passphrase') if passphrase is None: passphrase = getpass("\n" "test05GetDelegationWithBootstrappedTrustRoots" "passphrase: ") # Ensure any previously set trust root files are removed self._deleteTrustRootFiles() creds = self.clnt.getDelegation(thisSection['username'], passphrase, bootstrap=True) print "proxy credentials:" print ''.join(creds) def test07Destroy(self): # destroy credentials for a given user thisSection = self.cfg['test07Destroy'] sslKeyFilePassphrase = thisSection.get('sslKeyFilePassphrase') if sslKeyFilePassphrase is None: sslKeyFilePassphrase = getpass("\ntest07Destroy credential owner " "passphrase: ") self.clnt.destroy(thisSection['username'], sslCertFile=path.expandvars(thisSection['sslCertFile']), sslKeyFile=path.expandvars(thisSection['sslKeyFile']), sslKeyFilePassphrase=sslKeyFilePassphrase) print("Destroy creds for user %s" % thisSection['username'])