Ejemplo n.º 1
0
def _get_keytabs_from(host, port, proid, vips, spool_dir):
    """Get VIP keytabs from keytab locker server.
    """
    from treadmill.gssapiprotocol import jsonclient

    service = 'host@%s' % host
    _LOGGER.info('connecting: %s:%s, %s', host, port, service)
    client = jsonclient.GSSAPIJsonClient(host, int(port), service)

    try:
        if not client.connect():
            _LOGGER.warning('Cannot connect to %s:%s, %s', host, port, service)
            return False

        _LOGGER.debug('connected to: %s:%s, %s', host, port, service)

        request = {
            'action': 'get',
            'proid': proid,
            'vips': vips,
        }
        client.write_json(request)

        res = client.read_json()
        if '_error' in res:
            _LOGGER.warning('keytab locker internal err: %s', res['_error'])
            return False

        if not res['success']:
            _LOGGER.warning('get keytab err: %s', res['message'])
            return False

        for ktname, encoded in res['keytabs'].items():
            if encoded:
                _LOGGER.info('got keytab %s:%r', ktname,
                             hashlib.sha1(encoded).hexdigest())
                keytab_data = base64.urlsafe_b64decode(encoded)
                kt_file = os.path.join(spool_dir, ktname)
                _write_keytab(kt_file, keytab_data)
            else:
                _LOGGER.warning('got empty keytab %s', ktname)
                return False

        return True

    finally:
        client.disconnect()
Ejemplo n.º 2
0
def connect_endpoint(host, port):
    """open keytab2 connection
    """
    service = 'host@%s' % host
    _LOGGER.info('connecting: %s:%s, %s', host, port, service)
    client = jsonclient.GSSAPIJsonClient(host, int(port), service)

    if not client.connect():
        error = 'Cannot connect to {}:{}'.format(host, port)
        _LOGGER.error(error)
        raise keytabs2.KeytabClientError(error)

    _LOGGER.debug('connected to: %s:%s, %s', host, port, service)
    try:
        yield client
    finally:
        client.disconnect()
Ejemplo n.º 3
0
    def warpgate(policy_servers, service_principal):
        """Run warpgate container manager."""

        if not policy_servers:
            policy_servers = _policy_servers(context.GLOBAL.zk.conn)

        if not service_principal:
            service_principal = 'host'

        # Establish connection to the policy server and keep it open.
        #
        # Disconnecting from the policy server will retry with the next in the
        # list. If all fail, exit.
        #
        # In case policy servers change in Zookeeper, process will restart by
        # the supervisor, and re-evaluate.
        for hostport in policy_servers:
            _LOGGER.info('Connecting to %s', hostport)
            host, port = hostport.split(':')

            client = jsonclient.GSSAPIJsonClient(
                host, int(port), '{}@{}'.format(service_principal, host)
            )
            try:
                if not client.connect():
                    continue
                client.write_json({})
                policy = client.read_json()
                _LOGGER.info('Policy: %r', policy)
                # This will block, holding the connection.
                wait_for_reply = client.read()
                if wait_for_reply is None:
                    continue
            except socket.error as sock_err:
                _LOGGER.warning('Exception connecting to %s:%s - %s',
                                host, port, sock_err)
Ejemplo n.º 4
0
def run_client(policy_servers, service_principal, policy_name,
               tun_dev, tun_addr):
    """Run the WarpGate client.

    :param `list` policy_servers:
        List of WarpGate policy servers to try to connect to (in order).
    :param `str` service_principal:
        Kerberos service principal of the WarpGate servers.
    :param `str` policy name:
        Name of the policy to request.
    :param `str` tun_dev:
        Local device name to use for the tunnel.
    :param `str` tun_addr:
        IP address to use on the local device for the tunnel.
    """
    from treadmill.gssapiprotocol import jsonclient

    _init_network()

    # Establish connection to the policy server and keep it open.
    #
    # Disconnecting from the policy server will retry with the next in the
    # list. If all fail, exit.
    #
    # In case policy servers change in Zookeeper, process will restart by
    # the supervisor, and re-evaluate.
    nb_retries = 0
    while 0 <= nb_retries < len(policy_servers):
        for hostport in policy_servers:
            host, port = hostport.split(':')
            port = int(port)
            principal = '{}@{}'.format(service_principal, host)

            _LOGGER.info('Connecting to %s on %s:%s', principal, host, port)
            client = jsonclient.GSSAPIJsonClient(
                host, port, principal
            )
            try:
                if not client.connect():
                    nb_retries += 1
                    continue

                # We connected
                nb_retries = 0

                # Request the policy
                client.write_json(
                    {
                        'policy': policy_name
                    }
                )
                policy = client.read_json()
                _LOGGER.info('Policy[%s]: %r', policy_name, policy)
                # TODO: Validate policy response.
                if '_error' in policy:
                    # TODO: handle temporary(fail) vs permanent(denied)
                    #       failures. For now, always abort
                    nb_retries = -1
                    break

                _apply_policy(policy, tun_dev, tun_addr)

                # This will block, holding the connection.
                wait_for_reply = client.read()
                if wait_for_reply is None:
                    continue
            except socket.error as sock_err:
                _LOGGER.warning('Exception connecting to %s:%s - %s',
                                host, port, sock_err)