示例#1
0
def test_server_can_send_to_trustable_peer_identity():
    """
    Uses internal metadata of zmq.Frame.get() to fetch identity of sender
    """
    from pseud._gevent import Client, Server

    server_id = 'server'
    endpoint = 'tcp://127.0.0.1:8989'
    server_public, server_secret = zmq.curve_keypair()
    security_plugin = 'trusted_curve'

    server = Server(
        server_id,
        security_plugin=security_plugin,
        public_key=server_public,
        secret_key=server_secret,
    )
    server.bind(endpoint)

    bob_public, bob_secret = server.auth_backend.known_identities['bob']
    client = Client(
        server_id,
        user_id='bob',
        security_plugin=security_plugin,
        public_key=bob_public,
        secret_key=bob_secret,
        peer_public_key=server_public,
    )
    client.connect(endpoint)
    assert server.socket.mechanism == zmq.CURVE
    assert client.socket.mechanism == zmq.CURVE

    server.start()
    client.start()

    @server.register_rpc(with_identity=True)
    def echo(peer_identity, message):
        return peer_identity, message

    result = client.echo('one').get()
    if zmq.zmq_version_info() >= (4, 1, 0):
        assert result == ('bob', 'one')
    else:
        assert result == ('', 'one')
    server.stop()
    client.stop()
示例#2
0
def test_server_can_send_to_trustable_peer_identity():
    """
    Uses internal metadata of zmq.Frame.get() to fetch identity of sender
    """
    from pseud._gevent import Client, Server

    server_id = 'server'
    endpoint = 'tcp://127.0.0.1:8989'
    server_public, server_secret = zmq.curve_keypair()
    security_plugin = 'trusted_curve'

    server = Server(server_id, security_plugin=security_plugin,
                    public_key=server_public,
                    secret_key=server_secret,
                    )
    server.bind(endpoint)

    bob_public, bob_secret = server.auth_backend.known_identities['bob']
    client = Client(server_id,
                    user_id='bob',
                    security_plugin=security_plugin,
                    public_key=bob_public,
                    secret_key=bob_secret,
                    peer_public_key=server_public,
                    )
    client.connect(endpoint)
    assert server.socket.mechanism == zmq.CURVE
    assert client.socket.mechanism == zmq.CURVE

    server.start()
    client.start()

    @server.register_rpc(with_identity=True)
    def echo(peer_identity, message):
        return peer_identity, message

    result = client.echo('one').get()
    if zmq.zmq_version_info() >= (4, 1, 0):
        assert result == ('bob', 'one')
    else:
        assert result == ('', 'one')
    server.stop()
    client.stop()
示例#3
0
# coding: utf-8
__author__ = 'ceremcem'

import gevent
from gevent_actor import Actor
import zmq.green as zmq
from messages import *
from gevent import socket
from pprint import pprint
import copy

if zmq.zmq_version_info()[0] < 4:
    raise Exception("libzmq version should be >= 4.x")


def get_local_ip_addresses():
    import netifaces

    ip_addresses = list()
    interfaces = netifaces.interfaces()
    for i in interfaces:
        if i == 'lo':
            continue
        iface = netifaces.ifaddresses(i).get(netifaces.AF_INET)
        if iface:
            for j in iface:
                addr = j['addr']
                if addr != '127.0.0.1':
                    ip_addresses.append(addr)
    return ip_addresses
示例#4
0
class BaseRouter(object):
    '''Abstract base class of VIP router implementation.

    Router implementers should inherit this class and implement the
    setup() method to bind to appropriate addresses, set identities,
    setup authentication, etc, etc. The socket will be created by the
    start() method, which will then call the setup() method.  Once
    started, the socket may be polled for incoming messages and those
    messages are handled/routed by calling the route() method.  During
    routing, the log() method, which may be implemented, will be called
    to allow for debugging and logging. Custom subsystems may be
    implemented in the handle_subsystem() method. The socket will be
    closed when the stop() method is called.
    '''

    __slots__ = ['context', 'socket']

    def __init__(self, context=None):
        '''Initialize the object instance.

        If context is None (the default), the zmq global context will be
        used for socket creation.
        '''
        self.context = context or zmq.Context.instance()
        self.socket = None

    def start(self):
        '''Create the socket and call setup().

        The socket is save in the socket attribute. The setup() method
        is called at the end of the method to perform additional setup.
        '''
        self.socket = self.context.socket(ROUTER)
        self.socket.router_mandatory = True
        if not _GREEN:
            # Only set if not using zmq.green to avoid user warning
            self.socket.sndtimeo = 0
        self.setup()

    def stop(self, linger=1):
        '''Close the socket.'''
        self.socket.close(linger)

    def setup(self):
        '''Called from start() method to setup the socket.

        Implement this method to bind the socket, set identities and
        options, etc.
        '''
        raise NotImplementedError()

    @property
    def poll(self):
        '''Returns the underlying socket's poll method.'''
        return self.socket.poll

    def handle_subsystem(self, frames, user_id):
        '''Handle additional subsystems and provide a response.

        This method does nothing by default and may be implemented by
        subclasses to provide additional subsystems.

        frames is a list of zmq.Frame objects with the following
        elements:

          [SENDER, RECIPIENT, PROTOCOL, USER_ID, MSG_ID, SUBSYSTEM, ...]

        The return value should be None, if the subsystem is unknown, an
        empty list or False (or other False value) if the message was
        handled but does not require/generate a response, or a list of
        containing the following elements:

          [RECIPIENT, SENDER, PROTOCOL, USER_ID, MSG_ID, SUBSYSTEM, ...]

        '''
        pass

    def log(self, level, message, frames):
        '''Log what is happening in the router.

        This method does nothing by default and is meant to be
        overridden by router implementers. level is the same as in the
        standard library logging module, message is a brief description,
        and frames, if not None, is a list of frames as received from
        the sending peer.
        '''
        pass

    if zmq.zmq_version_info() >= (4, 1, 0):

        def lookup_user_id(self, sender, auth_token):
            '''Find and return a user identifier.

            Returns the UTF-8 encoded User-Id property from the sender
            frame or None if the authenticator did not set the User-Id
            metadata. May be extended to perform additional lookups.
            '''
            # pylint: disable=unused-argument
            # A user id might/should be set by the ZAP authenticator
            try:
                return sender.get('User-Id').encode('utf-8')
            except ZMQError as exc:
                if exc.errno != EINVAL:
                    raise
    else:

        def lookup_user_id(self, sender, auth_token):
            '''Find and return a user identifier.

            A no-op by default, this method must be overridden to map
            the sender and auth_token to a user ID. The returned value
            must be a string or None (if the token was not found).
            '''
            pass

    def route(self):
        '''Route one message and return.

        One message is read from the socket and processed. If the
        recipient is the router (empty recipient), the standard hello
        and ping subsystems are handled. Other subsystems are sent to
        handle_subsystem() for processing. Messages destined for other
        entities are routed appropriately.
        '''
        socket = self.socket
        log = self.log
        # Expecting incoming frames:
        #   [SENDER, RECIPIENT, PROTO, USER_ID, MSG_ID, SUBSYS, ...]
        frames = socket.recv_multipart(copy=False)
        log(DEBUG, 'incoming message', frames)
        if len(frames) < 6:
            # Cannot route if there are insufficient frames, such as
            # might happen with a router probe.
            if len(frames) == 2 and frames[0] and not frames[1]:
                log(DEBUG, 'router probe', frames)
            else:
                log(ERROR, 'unroutable message', frames)
            return
        sender, recipient, proto, auth_token, msg_id = frames[:5]
        if proto.bytes != PROTO:
            # Peer is not talking a protocol we understand
            log(ERROR, 'invalid protocol signature', frames)
            return
        user_id = self.lookup_user_id(sender, auth_token)
        if user_id is None:
            log(WARNING, 'missing user ID', frames)
            user_id = b''

        if not recipient.bytes:
            # Handle requests directed at the router
            subsystem = frames[5]
            name = subsystem.bytes
            if name == b'hello':
                frames = [
                    sender, recipient, proto, user_id, msg_id, _WELCOME,
                    _VERSION, socket.identity, sender
                ]
            elif name == b'ping':
                frames[:6] = [sender, recipient, proto, user_id, msg_id, _PONG]
            else:
                response = self.handle_subsystem(frames, user_id)
                if response is None:
                    # Handler does not know of the subsystem
                    log(ERROR, 'unknown subsystem', frames)
                    errnum, errmsg = _INVALID_SUBSYSTEM
                    frames = [
                        sender, recipient, proto, b'', msg_id, _ERROR, errnum,
                        errmsg, subsystem
                    ]
                elif not response:
                    # Subsystem does not require a response
                    return
                else:
                    frames = response
        else:
            # Route all other requests to the recipient
            frames[:4] = [recipient, sender, proto, user_id]

        # Expecting outgoing frames:
        #   [RECIPIENT, SENDER, PROTO, USER_ID, MSG_ID, SUBSYS, ...]
        try:
            # Try sending the message to its recipient
            socket.send_multipart(frames, flags=NOBLOCK, copy=False)
            log(DEBUG, 'outgoing message', frames)
        except ZMQError as exc:
            try:
                errnum, errmsg = _ROUTE_ERRORS[exc.errno]
            except KeyError:
                log(CRITICAL, 'unhandled exception: {}'.format(exc), frames)
                raise exc
            log(ERROR, 'send failure: {}'.format(errmsg.bytes), frames)
            if sender is not frames[0]:
                # Only send errors if the sender and recipient differ
                frames = [
                    sender, b'', proto, user_id, msg_id, _ERROR, errnum,
                    errmsg, recipient
                ]
                try:
                    socket.send_multipart(frames, flags=NOBLOCK, copy=False)
                    log(DEBUG, 'outgoing error', frames)
                except ZMQError as exc:
                    # Be silent about most errors when sending errors
                    if exc.errno not in _ROUTE_ERRORS:
                        log(CRITICAL, 'unhandled exception: {}'.format(exc),
                            frames)
                        raise
示例#5
0
def make_one_client(peer_identity,
                    heartbeat_plugin,
                    security_plugin='noop_auth_backend',
                    user_id=None,
                    password=None):
    from pseud._gevent import Client
    client = Client(peer_identity,
                    heartbeat_plugin=heartbeat_plugin,
                    security_plugin=security_plugin,
                    user_id=user_id,
                    password=password)
    return client


@pytest.mark.skipif(zmq.zmq_version_info() < (4, 1, 0),
                    reason='Needs pyzmq build with libzmq >= 4.1.0')
def test_basic_heartbeating():
    client_id = 'client'
    server_id = 'server'
    endpoint = 'ipc://here'
    heartbeat_backend = 'testing_heartbeat_backend'

    server = make_one_server(server_id, heartbeat_plugin=heartbeat_backend,
                             security_plugin='plain')

    client = make_one_client(server_id, heartbeat_plugin=heartbeat_backend,
                             security_plugin='plain',
                             user_id=client_id,
                             password=client_id)
    server.bind(endpoint)
# coding: utf-8
__author__ = 'ceremcem'

import gevent
from gevent_actor import Actor
import zmq.green as zmq
from messages import *
from gevent import socket
from pprint import pprint
import copy

if zmq.zmq_version_info()[0] < 4:
    raise Exception("libzmq version should be >= 4.x")

def get_local_ip_addresses():
    import netifaces

    ip_addresses = list()
    interfaces = netifaces.interfaces()
    for i in interfaces:
        if i == 'lo':
            continue
        iface = netifaces.ifaddresses(i).get(netifaces.AF_INET)
        if iface:
            for j in iface:
                addr = j['addr']
                if addr != '127.0.0.1':
                    ip_addresses.append(addr)
    return ip_addresses

示例#7
0
文件: test.py 项目: sublee/zeronimo
from psutil import Process
import pytest
from six import reraise
from six.moves import range
import zmq.green as zmq

from conftest import Application, link_sockets, rand_str, running, sync_pubsub
import zeronimo
from zeronimo.core import Background, uuid4_bytes
from zeronimo.exceptions import Rejected
from zeronimo.helpers import eintr_retry_zmq, socket_type_name
import zeronimo.messaging


warnings.simplefilter('always')
zmq_version_info = zmq.zmq_version_info()


def require_libzmq(version_info):
    args = version_info + ('x',) * (3 - len(version_info))
    reason = 'at least zmq-%s.%s.%s required' % args
    return pytest.mark.skipif(zmq_version_info < version_info, reason=reason)


def get_results(results):
    return [result.get() for result in results]


def find_objects(cls):
    gc.collect()
    return [o for o in gc.get_objects() if isinstance(o, cls)]
示例#8
0
def make_one_client(peer_identity,
                    heartbeat_plugin,
                    security_plugin='noop_auth_backend',
                    user_id=None,
                    password=None):
    from pseud._gevent import Client
    client = Client(peer_identity,
                    heartbeat_plugin=heartbeat_plugin,
                    security_plugin=security_plugin,
                    user_id=user_id,
                    password=password)
    return client


@pytest.mark.skipif(zmq.zmq_version_info() < (4, 1, 0),
                    reason='Needs pyzmq build with libzmq >= 4.1.0')
def test_basic_heartbeating():
    client_id = 'client'
    server_id = 'server'
    endpoint = 'ipc://here'
    heartbeat_backend = 'testing_heartbeat_backend'

    server = make_one_server(server_id,
                             heartbeat_plugin=heartbeat_backend,
                             security_plugin='plain')

    client = make_one_client(server_id,
                             heartbeat_plugin=heartbeat_backend,
                             security_plugin='plain',
                             user_id=client_id,