Example #1
0
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)
Example #3
0
    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'))
Example #4
0
    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)
Example #5
0
 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
Example #6
0
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
Example #8
0
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()
Example #9
0
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'))
Example #11
0
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)
Example #12
0
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()
Example #13
0
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 __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 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)
Example #16
0
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)
Example #17
0
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'})
Example #18
0
 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
Example #19
0
    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)
Example #20
0
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)
Example #21
0
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
Example #22
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)
Example #23
0
    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
Example #24
0
    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)
Example #26
0
    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
Example #27
0
 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])
Example #28
0
    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

Example #29
0
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 ":("
Example #30
0
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']))
Example #31
0
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)
Example #32
0
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)
Example #34
0
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 __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)
Example #37
0
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)
Example #38
0
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
Example #39
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
Example #40
0
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'])
Example #42
0
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))