Exemple #1
0
def _run_command_keys(options, reactor, personality):
    """
    Subcommand "crossbar keys".
    """
    log = make_logger()

    from crossbar.common.key import _read_node_key
    from crossbar.common.key import _read_release_key

    if options.generate:
        # Generate a new node key pair (2 files), load and check
        _maybe_generate_key(options.cbdir)
    else:
        # Print keys

        # Release (public) key
        release_pubkey = _read_release_key()

        # Node key
        node_key = _read_node_key(options.cbdir, private=options.private)

        if options.private:
            key_title = 'Crossbar.io Node PRIVATE Key'
        else:
            key_title = 'Crossbar.io Node PUBLIC Key'

        log.info('')
        log.info('{key_title}', key_title=hl('Crossbar Software Release Key', color='yellow', bold=True))
        log.info('base64: {release_pubkey}', release_pubkey=release_pubkey[u'base64'])
        log.info(release_pubkey[u'qrcode'].strip())
        log.info('')
        log.info('{key_title}', key_title=hl(key_title, color='yellow', bold=True))
        log.info('hex: {node_key}', node_key=node_key[u'hex'])
        log.info(node_key[u'qrcode'].strip())
        log.info('')
Exemple #2
0
def _run_command_keys(options, reactor, personality):
    """
    Subcommand "crossbar keys".
    """
    log = make_logger()

    # Generate a new node key pair (2 files), load and check
    _maybe_generate_key(options.cbdir)

    # Print keys

    # Release (public) key
    release_pubkey = _read_release_key()

    # Node key
    node_key = _read_node_key(options.cbdir, private=options.private)

    if options.private:
        key_title = 'Crossbar.io Node PRIVATE Key'
    else:
        key_title = 'Crossbar.io Node PUBLIC Key'

    log.info('')
    log.info('{key_title}',
             key_title=hl('Crossbar Software Release Key',
                          color='yellow',
                          bold=True))
    log.info('base64: {release_pubkey}',
             release_pubkey=release_pubkey['base64'])
    log.info(release_pubkey['qrcode'].strip())
    log.info('')
    log.info('{key_title}', key_title=hl(key_title, color='yellow', bold=True))
    log.info('hex: {node_key}', node_key=node_key['hex'])
    log.info(node_key['qrcode'].strip())
    log.info('')
Exemple #3
0
    def __init__(self, config=None, reactor=None, personality=None):
        # base ctor
        NativeProcess.__init__(self, config=config, reactor=reactor, personality=personality)

        # Release (public) key
        self._release_pubkey = _read_release_key()

        # Node (private) key (as a string, in hex)
        node_key_hex = _read_node_key(self.config.extra.cbdir, private=True)['hex']
        privkey = nacl.signing.SigningKey(node_key_hex, encoder=nacl.encoding.HexEncoder)

        # WAMP-cryptosign signing key
        self._node_key = cryptosign.SigningKey(privkey)
Exemple #4
0
import uuid
import pytest_twisted
from copy import deepcopy
from pprint import pformat

import txaio
txaio.use_twisted()

from autobahn.wamp.types import SubscribeOptions, PublishOptions
from crossbar.common.key import _read_node_key
from twisted.internet.defer import DeferredList, ensureDeferred

# do not directly import fixtures, or session-scoped ones will get run twice.
from ..helpers import *

node1_pubkey = _read_node_key('./test/cf1/.crossbar/', private=False)['hex']
node2_pubkey = _read_node_key('./test/cf2/.crossbar/', private=False)['hex']
node3_pubkey = _read_node_key('./test/cf3/.crossbar/', private=False)['hex']

node_rlink_ports = {
    "node1": 8090,
    "node2": 8091,
    "node3": 8092,
}
node_websocket_ports = {
    "node1": 9080,
    "node2": 9081,
    "node3": 9082,
}

# do not directly import fixtures, or session-scoped ones will get run twice.
from ..helpers import *

if False:
    node1_cbdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                               '../../cf1/.crossbar/')
    node2_cbdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                               '../../cf2/.crossbar/')
    node3_cbdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                               '../../cf3/.crossbar/')
else:
    node1_cbdir = './test/cf1/.crossbar/'
    node2_cbdir = './test/cf2/.crossbar/'
    node3_cbdir = './test/cf3/.crossbar/'

node1_pubkey = _read_node_key(node1_cbdir, private=False)['hex']
node2_pubkey = _read_node_key(node2_cbdir, private=False)['hex']
node3_pubkey = _read_node_key(node3_cbdir, private=False)['hex']

node_rlink_ports = {
    "node1": 8090,
    "node2": 8091,
    "node3": 8092,
}
node_websocket_ports = {
    "node1": 9080,
    "node2": 9081,
    "node3": 9082,
}

Exemple #6
0
def make_backend_connection(backend_config, frontend_session, cbdir):
    """
    Connects to a 'backend' session with the given config; returns a
    transport that is definitely connected (e.g. you can send a Hello
    right away).

    :param backend_config: Backend connection configuration, for example:

        .. code-block:: json
            {
                'auth': {
                    'cryptosign-proxy': {
                        'type': 'static'
                    }
                },
                'transport': {
                    'type': 'rawsocket',
                    'endpoint': {
                        'type': 'tcp',
                        'host': '127.0.0.1',
                        'port': 8442
                    },
                    'serializer': 'cbor',
                    'url': 'rs://localhost'
                }
            }

    :param frontend_session: The frontend proxy session for which to create a mapped backend connection.

    :param cbdir: The node directory.
    """

    from twisted.internet import reactor

    connected_d = Deferred()
    backend = _create_transport(0, backend_config['transport'])
    key = _read_node_key(cbdir, private=True)

    def create_session():
        session = ProxyBackendSession()

        # we will do cryptosign authentication to any backend
        if 'auth' in backend_config and 'cryptosign-proxy' in backend_config['auth']:
            session.add_authenticator(create_authenticator("cryptosign", privkey=key['hex']))

        # we allow anonymous authentication to just unix-sockets
        # currently. I don't think it's a good idea to allow any
        # anonymous auth to "real" backends over TCP due to
        # cross-protocol hijinks (and if a Web browser is running on
        # that machine, any website can try to access the "real"
        # backend)
        if 'auth' not in backend_config or 'anonymous-proxy' in backend_config['auth']:
            if backend_config['transport']['endpoint']['type'] == 'unix':
                session.add_authenticator(create_authenticator("anonymous"))
            else:
                raise RuntimeError('anonymous-proxy authenticator only allowed on Unix domain socket based transports, not type "{}"'.format(backend_config['transport']['endpoint']['type']))

        def connected(session, transport):
            connected_d.callback(session)
        session.on('connect', connected)
        return session

    # client-factory
    factory = _create_transport_factory(reactor, backend, create_session)
    endpoint = _create_transport_endpoint(reactor, backend_config['transport']['endpoint'])
    transport_d = endpoint.connect(factory)

    def _connected(proto):
        proto._proxy_other_side = frontend_session
        return proto

    def _error(f):
        if not connected_d.called:
            connected_d.errback(f)
    transport_d.addErrback(_error)
    transport_d.addCallback(_connected)

    return connected_d
Exemple #7
0
        def _backend_connected(backend_session):
            try:
                # wait for the WAMP-level transport to connect
                yield backend_session._on_connect

                # node private key
                key = _read_node_key(self._controller._cbdir, private=False)

                # FIXME
                authmethods = [
                    '{}-proxy'.format(x)
                    for x in backend_session._authenticators.keys()
                ]
                # authmethods = ['cryptosign-proxy']
                self.log.info('Proxy backend session authenticating using authmethods={authmethods} ..',
                              authmethods=authmethods)

                backend_session.join(
                    accept.realm,
                    authmethods=authmethods,
                    authid=None,
                    authrole=None,
                    authextra={
                        # for WAMP-cryptosign authentication of the proxy frontend
                        # to the backend router
                        "pubkey": key['hex'],

                        # forward authentication credentials of the connecting client
                        #
                        # the following are the effective (realm, authid, authrole) under
                        # which the client (proxy frontend connection) was successfully
                        # authenticated (using the authmethod+authprovider)
                        "proxy_realm": accept.realm,
                        "proxy_authid": accept.authid,
                        "proxy_authrole": accept.authrole,
                        "proxy_authmethod": accept.authmethod,
                        "proxy_authprovider": accept.authprovider,

                        # this is the authextra returned from the frontend authenticator, which
                        # would normally be returned to the client
                        "proxy_authextra": accept.authextra,
                    }
                )

                def _on_backend_joined(session, details):
                    self.log.info('Proxy backend session JOINED: session_id={backend_session_id} session={backend_session}, details={details}',
                                  backend_session_id=hlid(details.session), backend_session=session,
                                  pending_session_id=self._pending_session_id, details=details)
                    # we're ready now! store and return the backend session
                    self._backend_session = session

                    # we set the frontend session ID to that of the backend session mapped for our frontend session ..
                    self._session_id = details.session
                    # .. NOT our (fake) pending session ID (generated in the proxy worker)
                    # self._session_id = self._pending_session_id

                    # credentials of the backend session mapped for our frontend session
                    self._realm = details.realm
                    self._authid = details.authid
                    self._authrole = details.authrole

                    # this is the authextra returned for the backend session mapped for our frontend session
                    self._authextra = details.authextra

                    # authentication method & provider are the requested (and succeeding) ones
                    self._authmethod = accept.authmethod
                    self._authprovider = accept.authprovider

                    result.callback(session)

                backend_session.on('join', _on_backend_joined)
                return backend_session
            except Exception as e:
                self.log.failure()
                result.errback(e)