def sign(self, challenge): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") factory = Factory() factory.noisy = False factory.protocol = SSHAgentClient endpoint = UNIXClientEndpoint(self._reactor, os.environ["SSH_AUTH_SOCK"]) d = endpoint.connect(factory) @inlineCallbacks def on_connect(agent): # we are now connected to the locally running ssh-agent # that agent might be the openssh-agent, or eg on Ubuntu 14.04 by # default the gnome-keyring / ssh-askpass-gnome application blob = pack(['ssh-ed25519', self.public_key(binary=True)]) # now ask the agent signature_blob = yield agent.signData(blob, challenge) algo, signature = unpack(signature_blob) agent.transport.loseConnection() returnValue(signature) return d.addCallback(on_connect)
def main(): address = FilePath(sys.argv[1]) startLogging(sys.stdout) factory = Factory() factory.protocol = ReceiveFDProtocol factory.quiet = True endpoint = UNIXClientEndpoint(reactor, address.path) connected = endpoint.connect(factory) def succeeded(client): return client.whenDisconnected def failed(reason): print("Could not connect:", reason.getErrorMessage()) def disconnected(ignored): reactor.stop() connected.addCallbacks(succeeded, failed) connected.addCallback(disconnected) reactor.run()
def sign(self, challenge): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") factory = Factory() factory.noisy = False factory.protocol = SSHAgentClient endpoint = UNIXClientEndpoint(self._reactor, os.environ["SSH_AUTH_SOCK"]) d = endpoint.connect(factory) @inlineCallbacks def on_connect(agent): # we are now connected to the locally running ssh-agent # that agent might be the openssh-agent, or eg on Ubuntu 14.04 by # default the gnome-keyring / ssh-askpass-gnome application blob = _pack(['ssh-ed25519', self.public_key(binary=True)]) # now ask the agent signature_blob = yield agent.signData(blob, challenge) algo, signature = _unpack(signature_blob) agent.transport.loseConnection() returnValue(signature) return d.addCallback(on_connect)
def new(cls, pubkey=None, reactor=None): """ Create a proxy for a key held in SSH agent. :param pubkey: A string with a public Ed25519 key in SSH format. :type pubkey: unicode """ pubkey = _read_ssh_ed25519_pubkey(pubkey) if not reactor: from twisted.internet import reactor from twisted.internet.defer import inlineCallbacks, returnValue from twisted.internet.protocol import Factory from twisted.internet.endpoints import UNIXClientEndpoint from twisted.conch.ssh.agent import SSHAgentClient if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") factory = Factory() factory.noisy = False factory.protocol = SSHAgentClient endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) d = endpoint.connect(factory) @inlineCallbacks def on_connect(agent): keys = yield agent.requestIdentities() # if the key is found in ssh-agent, the raw public key (32 bytes), and the # key comment as returned from ssh-agent key_data = None key_comment = None for blob, comment in keys: raw = unpack(blob) algo = raw[0] if algo == u'ssh-ed25519': algo, _pubkey = raw if _pubkey == pubkey: key_data = _pubkey key_comment = comment.decode('utf8') break agent.transport.loseConnection() if key_data: key = signing.VerifyKey(key_data) returnValue(cls(key, key_comment, reactor)) else: raise Exception("Ed25519 key not held in ssh-agent") return d.addCallback(on_connect)
def open(self): """open the connection to the lircd socket""" def gotProtocol(result): """now we have a connection""" self.protocol = result self.protocol.wrapper = self print 'got lirc protocol' def gotNoProtocol(result): """something went wrong""" print "got no connection to lirc: %s" % result point = UNIXClientEndpoint(reactor, self.irwSocket, timeout=2) factory = ClientFactory() factory.protocol = LircProtocol point.connect(factory).addCallback(gotProtocol).addErrback(gotNoProtocol)
def fromCommandLine(cls, reactor, argv): config = EchoOptions() config.parseOptions(argv) keys = [] if config["identity"]: keyPath = os.path.expanduser(config["identity"]) if os.path.exists(keyPath): keys.append(readKey(keyPath)) knownHostsPath = FilePath(os.path.expanduser(config["knownhosts"])) if knownHostsPath.exists(): knownHosts = KnownHostsFile.fromPath(knownHostsPath) else: knownHosts = None if config["no-agent"] or "SSH_AUTH_SOCK" not in os.environ: agentEndpoint = None else: agentEndpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) return cls( reactor, config["host"], config["port"], config["username"], config["password"], keys, knownHosts, agentEndpoint, )
def fromConfig(cls, reactor): keys = [] if "identity" in _CONFIG: keyPath = os.path.expanduser(_CONFIG["identity"]) if os.path.exists(keyPath): keys.append(readKey(keyPath)) knownHostsPath = FilePath(os.path.expanduser(_CONFIG["knownhosts"])) if knownHostsPath.exists(): knownHosts = KnownHostsFile.fromPath(knownHostsPath) else: knownHosts = None if "no-agent" in _CONFIG or "SSH_AUTH_SOCK" not in os.environ: agentEndpoint = None else: agentEndpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) if "password" in _CONFIG: password = _CONFIG["password"] else: password = None return cls(reactor, _CONFIG["host"], _CONFIG["port"], _CONFIG["username"], password, keys, knownHosts, agentEndpoint)
def main(reactor): tor = yield txtorcon.connect( reactor, UNIXClientEndpoint(reactor, "/var/run/tor/control")) print("Connected to Tor version {}".format(tor.version)) url = 'https://www.torproject.org:443' print("Downloading {}".format(url)) resp = yield treq.get(url, agent=tor.web_agent()) print(" {} bytes".format(resp.length)) data = yield resp.text() print("Got {} bytes:\n{}\n[...]{}".format( len(data), data[:120], data[-120:], )) print("Creating a circuit") state = yield tor.create_state() circ = yield state.build_circuit() yield circ.when_built() print(" path: {}".format(" -> ".join([r.ip for r in circ.path]))) print("Downloading meejah's public key via above circuit...") resp = yield treq.get( 'https://meejah.ca/meejah.asc', agent=circ.web_agent(reactor, tor.config.socks_endpoint(reactor)), ) data = yield resp.text() print(data)
def get_connection_helper(reactor, address, username, port): """ Get a :class:`twisted.conch.endpoints._ISSHConnectionCreator` to connect to the given remote. :param reactor: Reactor to connect with. :param bytes address: The address of the remote host to connect to. :param bytes username: The user to connect as. :param int port: The port of the ssh server to connect to. :return _ISSHConnectionCreator: """ try: agentEndpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) except KeyError: agentEndpoint = None return _NewConnectionHelper(reactor, address, port, None, username, keys=None, password=None, agentEndpoint=agentEndpoint, knownHosts=KnownHostsFile.fromPath( FilePath("/dev/null")), ui=ConsoleUI(lambda: _ReadFile(b"yes")))
def start_tor(self): """ This function executes the workflow of starting the hidden service and returning its hostname """ self.info_callback("Attempting to start onion service on port: {} " "...".format(self.virtual_port)) if self.hidden_service_dir == "": if str(self.tor_control_host).startswith('unix:'): control_endpoint = UNIXClientEndpoint( reactor, self.tor_control_host[5:]) else: control_endpoint = TCP4ClientEndpoint(reactor, self.tor_control_host, self.tor_control_port) d = txtorcon.connect(reactor, control_endpoint) d.addCallback(self.create_onion_ep) d.addErrback(self.setup_failed) # TODO: add errbacks to the next two calls in # the chain: d.addCallback(self.onion_listen) d.addCallback(self.print_host) else: ep = "onion:" + str(self.virtual_port) + ":localPort=" ep += str(self.serving_port) # endpoints.TCPHiddenServiceEndpoint creates version 2 by # default for backwards compat (err, txtorcon needs to update that ...) ep += ":version=3" ep += ":hiddenServiceDir=" + self.hidden_service_dir onion_endpoint = serverFromString(reactor, ep) d = onion_endpoint.listen(self.proto_factory) d.addCallback(self.print_host_filesystem)
class Client: def __init__(self, addr, reactor, callback, plant, name, pid, wait_result): self.addr = addr self.reactor = reactor self.protocol = None self.deferred = defer.Deferred() self.deferred.addCallback(self.connected) self.factory = ClientFactory(callback, plant, name, pid, wait_result, self.deferred) self.endpoint = UNIXClientEndpoint(reactor, addr) def connect(self): return self.endpoint.connect(self.factory) def disconnect(self): if self.protocol is not None: self.protocol.disconnect() def connected(self, protocol): self.protocol = protocol def notify_death(self, wait_result): """Returns true if death ceritificate has been sent, false otherwise """ if self.protocol is None: logging.error("Cannot report exit status because not connected") return False elif self.protocol.state == ACCEPTED: self.protocol.notify_death(wait_result) else: logging.info("Not notifying server of death because connection is not in ACCEPTED state (state = {})".format(self.protocol.state)) return self.protocol.state >= ACCEPTED
def testSSH101(self): def finished(): pass keypaths = [ # '/data/dev/beholder/sys/ssh-keys/client_rsa.pub', '/data/dev/beholder/sys/ssh-keys/client_rsa' ] keys = [] for keyPath in keypaths: if os.path.exists(keyPath): keys.append(readKey(keyPath)) knownHostsPath = '/home/jan/.ssh/known_hosts' knownHosts = KnownHostsFile.fromPath(FilePath(knownHostsPath)) # for entry in knownHosts.iterentries(): # if entry.matchesHost(b"[localhost]:2222"): # print("yess!!!!!!!!!!!!!!!!!!!!!") # print(entry) agentEndpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) client = SSHCmdClient(b"localhost", 2222, b"user", keys=keys, knownhosts=knownHosts, agent=None) self.assertIsNotNone(client) endpoint = client.newConnection("ls") self.assertIsNotNone(endpoint) factory = Factory() factory.protocol = TestProtocol d = endpoint.connect(factory) d.addCallback(finished) return d
def start_tor(self): """ This function executes the workflow of starting the hidden service. """ if not self.local_port: control_host = jm_single().config.get("PAYJOIN", "tor_control_host") control_port = int(jm_single().config.get("PAYJOIN", "tor_control_port")) if str(control_host).startswith('unix:'): control_endpoint = UNIXClientEndpoint(reactor, control_host[5:]) else: control_endpoint = TCP4ClientEndpoint(reactor, control_host, control_port) d = txtorcon.connect(reactor, control_endpoint) d.addCallback(self.create_onion_ep) d.addErrback(self.setup_failed) else: d = Deferred() d.callback(None) d.addCallback(self.create_onion_ep) # TODO: add errbacks to the next two calls in # the chain: d.addCallback(self.onion_listen) d.addCallback(self.print_host)
def __init__(self, addr, reactor, callback, plant, name, pid, wait_result): self.addr = addr self.reactor = reactor self.protocol = None self.deferred = defer.Deferred() self.deferred.addCallback(self.connected) self.factory = ClientFactory(callback, plant, name, pid, wait_result, self.deferred) self.endpoint = UNIXClientEndpoint(reactor, addr)
def __init__(self, reactor, socket_path=None): super(IPCWorkerService, self).__init__() self.reactor = reactor self.socket_path = socket_path if self.socket_path is None: self.socket_path = get_ipc_socket_path() self.endpoint = UNIXClientEndpoint(reactor, self.socket_path) self.protocol = None
def open(self): """open the connection to the lircd socket""" def gotProtocol(result): """now we have a connection""" self.protocol = result self.protocol.wrapper = self logDebug(self, None, 'got lirc protocol') def gotNoProtocol(result): """something went wrong""" print "got no connection to lirc: %s" % result point = UNIXClientEndpoint(reactor, self.irwSocket, timeout=2) factory = ClientFactory() factory.protocol = LircProtocol point.connect(factory).addCallback(gotProtocol).addErrback( gotNoProtocol)
def passTo(self, host, protocol): orig_socket = protocol.transport.socket if not host: host = b'default' try: for vhost in self.vhosts: if vhost.hostname.match(host): dest_socket = vhost.socket endpoint = UNIXClientEndpoint(reactor, dest_socket) connected = endpoint.connect(Factory.forProtocol(Protocol)) connected.addCallback( partial(self.passClientTo, orig_socket)) connected.addBoth(partial(self.disconnect, protocol)) return finally: pass
def connectClient(self): class TraphClientFactory(Factory): def buildProtocol(this, addr): return self.client t = TraphClientFactory() if not self.corpus.factory.chatty: t.noisy = False UNIXClientEndpoint(reactor, self.socket).connect(t)
def main(reactor, *argv): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") factory = Factory() factory.protocol = SSHAgentClient endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) d = endpoint.connect(factory) @inlineCallbacks def on_connect(proto): print("connected to agent. keys held currently:") keys = yield proto.requestIdentities() for blob, comment in keys: print("Key: {}".format(comment)) proto.transport.loseConnection() return d.addCallback(on_connect)
def agent_for_socks_port(reactor, torconfig, socks_config, pool=None): """ This returns a Deferred that fires with an object that implements :class:`twisted.web.iweb.IAgent` and is thus suitable for passing to ``treq`` as the ``agent=`` kwarg. Of course can be used directly; see `using Twisted web cliet <http://twistedmatrix.com/documents/current/web/howto/client.html>`_. If you have a :class:`txtorcon.Tor` instance already, the preferred API is to call :meth:`txtorcon.Tor.web_agent` on it. :param torconfig: a :class:`txtorcon.TorConfig` instance. :param socks_config: anything valid for Tor's ``SocksPort`` option. This is generally just a TCP port (e.g. ``9050``), but can also be a unix path like so ``unix:/path/to/socket`` (Tor has restrictions on the ownership/permissions of the directory containing ``socket``). If the given SOCKS option is not already available in the underlying Tor instance, it is re-configured to add the SOCKS option. """ # :param tls: True (the default) will use Twisted's default options # with the hostname in the URI -- that is, TLS verification # similar to a Browser. Otherwise, you can pass whatever Twisted # returns for `optionsForClientTLS # <https://twistedmatrix.com/documents/current/api/twisted.internet.ssl.optionsForClientTLS.html>`_ socks_config = str(socks_config) # sadly, all lists are lists-of-strings to Tor :/ if socks_config not in torconfig.SocksPort: txtorlog.msg("Adding SOCKS port '{}' to Tor".format(socks_config)) torconfig.SocksPort.append(socks_config) try: yield torconfig.save() except Exception as e: raise RuntimeError( "Failed to reconfigure Tor with SOCKS port '{}': {}".format( socks_config, str(e) ) ) if socks_config.startswith('unix:'): socks_ep = UNIXClientEndpoint(reactor, socks_config[5:]) else: if ':' in socks_config: host, port = socks_config.split(':', 1) else: host = '127.0.0.1' port = int(socks_config) socks_ep = TCP4ClientEndpoint(reactor, host, port) returnValue( Agent.usingEndpointFactory( reactor, _AgentEndpointFactoryUsingTor(reactor, socks_ep), pool=pool, ) )
def __init__(self, reactor, socket_path=None): super().__init__() self.reactor = reactor self.socket_path = socket_path if self.socket_path is None: self.socket_path = get_ipc_socket_path() self.endpoint = UNIXClientEndpoint(reactor, self.socket_path) self._protocol = None self.protocol = DeferredValue() self.processId = DeferredValue()
def setUp(self): path = self.mktemp() self.app = fixture(self) self.port = reactor.listenUNIX( path, Site(self.app.resource()), ) self.addCleanup(self.port.stopListening) self.agent = ProxyAgent(UNIXClientEndpoint(reactor, path), reactor) super(RealTests, self).setUp()
def __init__(self, args=None): '''Args must be an object with the following attributes: socketpath, verbose Suitable defaults will be supplied.''' # Pass command line args to ProtocolIVSHMSG, then open logging. if args is None: args = argparse.Namespace() for arg, default in self._required_arg_defaults.items(): setattr(args, arg, getattr(args, arg, default)) self.args = args # checkPID looks for <socketpath>.lock which the server sets up # as a symlink to file named <PID> E = UNIXClientEndpoint(TIreactor, args.socketpath, timeout=1, checkPID=False) E.connect(self)
def get_agent(self): """ Get the SSH agent endpoint. """ reactor = self.reactor if "SSH_AUTH_SOCK" in os.environ: agent_endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) else: agent_endpoint = None return agent_endpoint
def assemble(): transport = { "type": "rawsocket", "url": "ws://localhost/ws", "endpoint": UNIXClientEndpoint(reactor, sock_path), "serializer": "cbor", } component = Component(transports=[transport], realm="deskconn", session_factory=GPIOComponent) component._transports[0].max_retries = 0 return component
def ensure_agent_has_ssh_key(reactor, key): """ Check that the running ssh-agent has the private key corresponding to the provided key. :param reactor: The reactor to use to connect to the agent. :param Key key: The ssh key to check for in the agent. :return Deferred: That fires with a successful result if the key is found. Otherwise, fails with ``AgentNotFound`` or ``KeyNotFound``. """ try: agent_socket = os.environ["SSH_AUTH_SOCK"] except KeyError: return fail(AgentNotFound()) if not key.isPublic(): key = key.public() action = start_action( action_type="flocker.provision.ssh:check_agent_has_ssh_keys", key_fingerprint=key.fingerprint(), agent_socket=agent_socket) with action.context(): agent_endpoint = UNIXClientEndpoint(reactor, agent_socket) agent_protocol = SSHAgentClient() connected = DeferredContext( connectProtocol(agent_endpoint, agent_protocol)) connected.addCallback(lambda _: agent_protocol.requestIdentities()) def check_keys(results): for key_data, comment in results: agent_key = Key.fromString(key_data, type='blob') Message.new(message_type="flocker.provision.ssh:agent_key", key_fingerprint=agent_key.fingerprint(), commnet=comment).write() if agent_key == key: return True raise KeyNotFound(expected_key=key) connected.addCallback(check_keys) def disconnect(result): agent_protocol.transport.loseConnection() return result connected.addBoth(disconnect) return connected.addActionFinish()
def query(ctx): """" Execute subcommand through UNIX domain socket client. """ if not ctx.opts.argv: print("No command %s" % ctx.opts.argv[0], file=ctx.err) return 1 address = FilePath(ctx.opts.flags.address) factory = Factory() factory.ctx = ctx ctx.rs = 0 factory.protocol = QueryProtocol factory.quiet = True factory.cmd = ' '.join(ctx.opts.argv) # DEBUG: # print('Passthrough command to backend via socket: %r' % factory.cmd, file=sys.stderr) endpoint = UNIXClientEndpoint(reactor, address.path) connected = endpoint.connect(factory) def succeeded(client): return client.whenDisconnected def failed(reason): print("Could not connect:", reason.getErrorMessage(), file=ctx.err) def disconnected(ignored): reactor.stop() connected.addCallbacks(succeeded, failed) connected.addCallback(disconnected) reactor.run() return factory.ctx.rs
def main(reactor, *argv): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) proto = yield endpoint.connect(Factory.forProtocol(SSHAgentClient)) print("connected to agent. keys held currently:") for blob, comment in (yield proto.requestIdentities()): raw = unpack(blob) algo = raw[0] if algo == u'ssh-rsa': algo, exponent, modulus = raw print("RSA key: {} {} 0x{} {}: 0x{} ..".format( comment, algo, b2a_hex(exponent), len(modulus), b2a_hex(modulus)[:16])) print(b2a_base64(blob)) elif algo == u'ssh-ed25519': algo, pubkey = raw print("Ed25519 key: {} {} {}".format(comment, algo, b2a_hex(pubkey))) else: print("Key of unknown type {}".format(algo)) proto.transport.loseConnection()
def main(reactor, *argv): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) proto = yield endpoint.connect(Factory.forProtocol(SSHAgentClient)) print("connected to agent. keys held currently:") for blob, comment in (yield proto.requestIdentities()): raw = unpack(blob) algo = raw[0] if algo == u"ssh-rsa": algo, exponent, modulus = raw print( "RSA key: {} {} 0x{} {}: 0x{} ..".format( comment, algo, b2a_hex(exponent), len(modulus), b2a_hex(modulus)[:16] ) ) print(b2a_base64(blob)) elif algo == u"ssh-ed25519": algo, pubkey = raw print("Ed25519 key: {} {} {}".format(comment, algo, b2a_hex(pubkey))) else: print("Key of unknown type {}".format(algo)) proto.transport.loseConnection()
def main(reactor): ep = UNIXClientEndpoint(reactor, '/var/run/tor/control') tor = yield txtorcon.connect(reactor, ep) def log(msg): print msg print "Connected to a Tor version", tor.protocol.version for event in ['INFO', 'NOTICE', 'WARN', 'ERR']: tor.protocol.add_event_listener(event, log) is_current = yield tor.protocol.get_info('status/version/current') version = yield tor.protocol.get_info('version') print("Version '{}', is_current={}".format( version, is_current['status/version/current'])) yield defer.Deferred()
def setUp(self): # We use relpath as you can't bind to a path longer than 107 # chars. You can easily get an absolute path that long # from mktemp, but rather strangely bind doesn't care # how long the abspath is, so we call relpath here and # it should work as long as our method names aren't too long path = os.path.relpath(self.mktemp()) self.app = fixture(self) self.port = reactor.listenUNIX( path, Site(self.app.resource()), ) self.addCleanup(self.port.stopListening) self.agent = ProxyAgent(UNIXClientEndpoint(reactor, path), reactor) super(RealTests, self).setUp()
def installPools(pools, maxClients=5, reactor=None): if reactor is None: from twisted.internet import reactor for name, pool in pools.items(): if pool["ClientEnabled"]: if pool.get("MemcacheSocket"): ep = UNIXClientEndpoint(reactor, pool["MemcacheSocket"]) else: ep = GAIEndpoint(reactor, pool["BindAddress"], pool["Port"]) _installPool( name, pool["HandleCacheTypes"], ep, maxClients, reactor, )
def ConnectToChaperone(cls, reactor, chaperoneDetails, playgroundAddress): if cls.__muxer: cls.__muxer.chaperone.connectionLost("Chaperone and/or Address Change") if cls.__muxer.chaperone.transport: cls.__muxer.chaperone.transport.loseConnection() if len(chaperoneDetails) == 2: addr, port = chaperoneDetails chaperoneEndpoint = TCP4ClientEndpoint(reactor, addr, int(port)) elif len(chaperoneDetails) == 1: chaperoneEndpoint = UNIXClientEndpoint(reactor, chaperoneDetails[0]) else: raise ValueError('expected (addr, port) or (socket,) tuple but got %s' % chaperoneDetails) cls.__muxer = BotMuxer(playgroundAddress) cls.__playgroundAddress = playgroundAddress return connectProtocol(chaperoneEndpoint, cls.__muxer.chaperone)
def main(reactor): """ Close all open streams and circuits in the Tor we connect to """ control_ep = UNIXClientEndpoint(reactor, '/var/run/tor/control') tor = yield txtorcon.connect(reactor, control_ep) state = yield tor.create_state() print("Closing all circuits:") for circuit in list(state.circuits.values()): path = '->'.join(map(lambda r: r.id_hex, circuit.path)) print("Circuit {} through {}".format(circuit.id, path)) for stream in circuit.streams: print(" Stream {} to {}".format(stream.id, stream.target_host)) yield stream.close() print(" closed") yield circuit.close() print("closed") yield tor.quit()
def start_tor(self): """ This function executes the workflow of starting the hidden service and returning its hostname """ self.info_callback("Attempting to start onion service on port: {} " "...".format(self.port)) if str(self.tor_control_host).startswith('unix:'): control_endpoint = UNIXClientEndpoint(reactor, self.tor_control_host[5:]) else: control_endpoint = TCP4ClientEndpoint(reactor, self.tor_control_host, self.tor_control_port) d = txtorcon.connect(reactor, control_endpoint) d.addCallback(self.create_onion_ep) d.addErrback(self.setup_failed) # TODO: add errbacks to the next two calls in # the chain: d.addCallback(self.onion_listen) d.addCallback(self.print_host)
async def _main(reactor): if False: print("launching tor") tor = await txtorcon.launch(reactor, progress_updates=print) else: tor = await txtorcon.connect( reactor, UNIXClientEndpoint(reactor, "/var/run/tor/control"), ) print("Connected to tor {}".format(tor.version)) # here, we've just chosen 1234 as the port. We have three other # options: # - select a random, unused one ourselves # - put "ports=[80]" below, and find out which port txtorcon # selected after # - use a Unix-domain socket # we create a Tor onion service on a specific local TCP port print("Creating onion service") onion = await tor.create_onion_service( ports=[(80, 1234) # 80 is the 'public' port, 1234 is local ], private_key= 'RSA1024:MIICWwIBAAKBgQCmHEH1y7/RUUeeaSTgB3iQFfWMep38JDlAbDoEPltRxzgEh8bXMsNbemdiCuZmJVni96KrRh2/I2NwWi6C81xfcA8BjVzdCmEbL1B+KOeqZlrjoEMQl56NpbXIIzFZdyILaQtv3EZMoShNHSkta6e66oWUu2B2fkluwYyPxRAdvQIDAQABAoGAYkObHX2PlpK/jE1k3AZvYsUqwhSTOuJu39ZmJ7Z/rQvt7ngnv4wvFwF9APmzvD9iQir+FtXeqQCVRZSDqUGvpW0WgA+8aDA3BGWCZwKhWRWj18RLjsMX+wKP6OBpSIlNjELU8zc5PWWsCmT7AqAdVD7vqp2895LiP4M8vwwZB30CQQDb/fjoG1VWpFWXgjRHEYOoPj7d7J5FcRrbSgc57lvMv/2+4OVl2aRaGEjigfBnR7Pjbyxv/5K1h078PBWNumjPAkEAwUyN3SLJOMBM74LS2jh9AB/sNitLT7/O1f8zT0siC58TmTbeZsj3VqSsmrUiVSptQcOm+5F0UPvYxsI+B2UbswJAdV9dq8jZkS6AlCNd7QUFL4B2XkVedEJSR+mJTXlE9UsCARNQkTS7oW4PhPo633+8FH4+QUskZUHZ/G26OjHYtQJAIAKyd418LzbBRuSuUE8MfEnND0dqKGHGOfASKi5yC+SjFTtd5z2eoC2TG+elMN9eyoZBD+YNkh+yzW97YDQhOwJAKFKLmdlJve1lJah1ZllZfk2ipNeYVX+q1Mv7TE6IXGqU/Xt3HS8h9Zd8ml/Yms1z9X7hFIjQ/XcSiJhqcin8Vg==', version=2, # FIXME use v3; using old tor for now progress=print, ) # we're now listening on some onion service URL and re-directing # public port 80 requests to local TCP port 1234. app = create_aio_application() runner = web.AppRunner(app) await as_deferred(runner.setup()) site = web.TCPSite(runner, 'localhost', 1234) await as_deferred(site.start()) # now we're completely set up print("Onion site on http://{}".format(onion.hostname)) await Deferred()
else: print k,v if 'defaults' in sys.argv: print "Set to default value:" for k in defaults: print "# %s" % k reactor.stop() def setup_failed(arg): print "SETUP FAILED",arg reactor.stop() def bootstrap(c): conf = TorConfig(c) conf.post_bootstrap.addCallback(setup_complete).addErrback(setup_failed) print "Connection is live, bootstrapping state..." if os.stat('/var/run/tor/control').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH): print "using control socket" point = UNIXClientEndpoint(reactor, "/var/run/tor/control") else: point = TCP4ClientEndpoint(reactor, "localhost", 9051) d = point.connect(TorProtocolFactory()) # do not use addCallbacks() here, in case bootstrap has an error d.addCallback(bootstrap).addErrback(setup_failed) reactor.run()
def main(reactor): ep = UNIXClientEndpoint(reactor, '/var/run/postgresql/.s.PGSQL.5432') fact = ClientFactory.forProtocol(PostgresProtocol) proto = yield ep.connect(fact) # for i in range(5000): res = yield proto.runQuery('SELECT * from entries limit 5')
def main(reactor, *argv): if "SSH_AUTH_SOCK" not in os.environ: raise Exception("no ssh-agent is running!") factory = Factory() factory.protocol = SSHAgentClient endpoint = UNIXClientEndpoint(reactor, os.environ["SSH_AUTH_SOCK"]) d = endpoint.connect(factory) @inlineCallbacks def on_connect(agent): # we are now connected to the locally running ssh-agent # that agent might be the openssh-agent, or eg on Ubuntu 14.04 by # default the gnome-keyring / ssh-askpass-gnome application print("connected to ssh-agent!") print("keys currently held in ssh-agent:\n") keys = yield agent.requestIdentities() for blob, comment in keys: print(comment) raw = unpack(blob) algo = raw[0] if algo == u'ssh-rsa': algo, exponent, modulus = raw print("RSA key: {} {} 0x{} {}: 0x{} ..".format(comment, algo, b2a_hex(exponent), len(modulus), b2a_hex(modulus)[:16])) print(b2a_base64(blob)) elif algo == u'ssh-ed25519': algo, pubkey = raw print("Ed25519 key: {} {} {}".format(comment, algo, b2a_hex(pubkey))) # we will now ask the ssh-agent to sign some data using the private # key that corresponds to the public key that we selected print("sign some data:\n") # message to sign message = 'Hello, world!' # the public key that corrsponds to the private key we ask the agent to sign with key_blob, key_comment = keys[-1] # now ask the agent signature_blob = yield agent.signData(key_blob, message) algo, signature = unpack(signature_blob) print(algo) print(b2a_base64(signature)) # we now verify the signature using cryptography. # https://cryptography.io/en/latest/hazmat/primitives/asymmetric/serialization/#cryptography.hazmat.primitives.serialization.load_ssh_public_key public_key = load_ssh_public_key("ssh-rsa {} {}".format(b2a_base64(key_blob), key_comment), backend=default_backend()) isinstance(public_key, rsa.RSAPublicKey) verifier = public_key.verifier(signature, padding.PKCS1v15(), hashes.SHA1()) verifier.update(message) # here we can provoke a failing signature to check that it actually works provoke_signature_failure = False if provoke_signature_failure: verifier.update('make the sig fail') try: verifier.verify() except InvalidSignature: print("** Signature is invalid!! **") else: print("Signature looks good.") # that's it. say goodbye. print("disconnecting ..") agent.transport.loseConnection() return d.addCallback(on_connect)
def build_tor_connection(connection, build_state=True, wait_for_proto=True, password_function=lambda: None): """ This is used to build a valid TorState (which has .protocol for the TorControlProtocol). For example:: from twisted.internet import reactor from twisted.internet.endpoints import TCP4ClientEndpoint import txtorcon def example(state): print "Fully bootstrapped state:",state print " with bootstrapped protocol:",state.protocol d = txtorcon.build_tor_connection(TCP4ClientEndpoint(reactor, "localhost", 9051)) d.addCallback(example) reactor.run() :param password_function: See :class:`txtorcon.TorControlProtocol` :param build_state: If True (the default) a TorState object will be built as well. If False, just a TorControlProtocol will be returned via the Deferred. :return: a Deferred that fires with a TorControlProtocol or, if you specified build_state=True, a TorState. In both cases, the object has finished bootstrapping (i.e. TorControlProtocol.post_bootstrap or TorState.post_bootstap has fired, as needed) """ if IStreamClientEndpoint.providedBy(connection): endpoint = connection elif isinstance(connection, tuple): if len(connection) == 2: reactor, socket = connection if (os.path.exists(socket) and os.stat(socket).st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH)): endpoint = UNIXClientEndpoint(reactor, socket) else: raise ValueError('Can\'t use "%s" as a socket' % (socket, )) elif len(connection) == 3: endpoint = TCP4ClientEndpoint(*connection) else: raise TypeError('Expected either a (reactor, socket)- or a ' '(reactor, host, port)-tuple for argument ' '"connection", got %s' % (connection, )) else: raise TypeError('Expected a (reactor, socket)- or a (reactor, host, ' 'port)-tuple or an object implementing IStreamClient' 'Endpoint for argument "connection", got %s' % (connection, )) d = endpoint.connect(TorProtocolFactory(password_function=password_function)) if build_state: d.addCallback(build_state if callable(build_state) else _build_state) elif wait_for_proto: d.addCallback(wait_for_proto if callable(wait_for_proto) else _wait_for_proto) return d
def start_component(self, component, router): """ Starts a Class or WAMPlet in this component container. """ if component['type'] == 'wamplet': try: dist = component['dist'] name = component['entry'] if self.debug: log.msg("Worker {}: starting WAMPlet '{}/{}' in realm '{}' ..".format(self._pid, dist, name, router['realm'])) ## make is supposed to make instances of ApplicationSession make = pkg_resources.load_entry_point(dist, 'autobahn.twisted.wamplet', name) except Exception as e: log.msg("Worker {}: failed to import class - {}".format(e)) raise ApplicationError("crossbar.error.class_import_failed", str(e)) elif component['type'] == 'class': try: klassname = component['name'] if self.debug: log.msg("Worker {}: starting class '{}' in realm '{}' ..".format(self._pid, klassname, router['realm'])) import importlib c = klassname.split('.') mod, kls = '.'.join(c[:-1]), c[-1] app = importlib.import_module(mod) ## make is supposed to be of class ApplicationSession make = getattr(app, kls) except Exception as e: log.msg("Worker {}: failed to import class - {}".format(e)) raise ApplicationError("crossbar.error.class_import_failed", str(e)) else: raise ApplicationError("crossbar.error.invalid_configuration", "unknown component type '{}'".format(component['type'])) def create(): cfg = ComponentConfig(realm = router['realm'], extra = component.get('extra', None)) c = make(cfg) return c ## create a WAMP-over-WebSocket transport client factory ## from autobahn.twisted.websocket import WampWebSocketClientFactory transport_factory = WampWebSocketClientFactory(create, router['url'], debug = self.debug) transport_factory.setProtocolOptions(failByDrop = False) ## start a WebSocket client from an endpoint ## from twisted.internet import reactor from twisted.internet.endpoints import TCP4ClientEndpoint, SSL4ClientEndpoint, UNIXClientEndpoint from twisted.internet.endpoints import clientFromString from crossbar.twisted.tlsctx import TlsClientContextFactory if False: self._client = clientFromString(reactor, router['endpoint']) else: try: endpoint_config = router.get('endpoint') ## a TCP4 endpoint ## if endpoint_config['type'] == 'tcp': ## the host to connect ot ## host = str(endpoint_config['host']) ## the port to connect to ## port = int(endpoint_config['port']) ## connection timeout in seconds ## timeout = int(endpoint_config.get('timeout', 10)) if 'tls' in endpoint_config: ctx = TlsClientContextFactory() ## create a TLS client endpoint ## self._client = SSL4ClientEndpoint(reactor, host, port, ctx, timeout = timeout) else: ## create a non-TLS client endpoint ## self._client = TCP4ClientEndpoint(reactor, host, port, timeout = timeout) ## a Unix Domain Socket endpoint ## elif endpoint_config['type'] == 'unix': ## the path ## path = os.path.abspath(os.path.join(self._cbdir, endpoint_config['path'])) ## connection timeout in seconds ## timeout = int(endpoint_config['type'].get('timeout', 10)) ## create the endpoint ## self._client = UNIXClientEndpoint(reactor, path, timeout = timeout) else: raise ApplicationError("crossbar.error.invalid_configuration", "invalid endpoint type '{}'".format(endpoint_config['type'])) except Exception as e: log.msg("endpoint creation failed: {}".format(e)) raise e retry = True retryDelay = 1000 def try_connect(): if self.debug: log.msg("Worker {}: connecting to router ..".format(self._pid)) d = self._client.connect(transport_factory) def success(res): if self.debug: log.msg("Worker {}: client connected to router".format(self._pid)) def error(err): log.msg("Worker {}: client failed to connect to router - {}".format(self._pid, err)) if retry: log.msg("Worker {}: retrying in {} ms".format(self._pid, retryDelay)) reactor.callLater(float(retryDelay) / 1000., try_connect) else: log.msg("Worker {}: giving up.".format(seld._pid)) d.addCallbacks(success, error) try_connect()
def getDBusEndpoints(reactor, busAddress, client=True): """ Creates DBus endpoints. @param busAddress: 'session', 'system', or a valid bus address as defined by the DBus specification. If 'session' (the default) or 'system' is supplied, the contents of the DBUS_SESSION_BUS_ADDRESS or DBUS_SYSTEM_BUS_ADDRESS environment variables will be used for the bus address, respectively. If DBUS_SYSTEM_BUS_ADDRESS is not set, the well-known address unix:path=/var/run/dbus/system_bus_socket will be used. @type busAddress: C{string} @rtype: C{list} of L{twisted.internet.interfaces.IStreamServerEndpoint} @returns: A list of endpoint instances """ if busAddress == 'session': addrString = os.environ.get('DBUS_SESSION_BUS_ADDRESS', None) if addrString is None: raise Exception('DBus Session environment variable not set') elif busAddress == 'system': addrString = os.environ.get('DBUS_SYSTEM_BUS_ADDRESS', 'unix:path=/var/run/dbus/system_bus_socket') else: addrString = busAddress #XXX Add documentation about extra key=value parameters in address string # such as nonce-tcp vs tcp which use same endpoint class epl = list() for ep_addr in addrString.split(';'): d = dict() kind = None ep = None for c in ep_addr.split(','): if c.startswith('unix:'): kind = 'unix' c = c[5:] elif c.startswith('tcp:'): kind = 'tcp' c = c[4:] elif c.startswith('nonce-tcp:'): kind = 'tcp' c = c[10:] d['nonce-tcp'] = True elif c.startswith('launchd:'): kind = 'launchd' c = c[7:] if '=' in c: k,v = c.split('=') d[k] = v if kind == 'unix': if 'path' in d: path = d['path'] elif 'tmpdir' in d: path = d['tmpdir'] + '/dbus-' + str(os.getpid()) elif 'abstract' in d: path = '\0' + d['abstract'] if client: ep = UNIXClientEndpoint(reactor, path=path) else: ep = UNIXServerEndpoint(reactor, address=path) elif kind == 'tcp': if client: ep = TCP4ClientEndpoint(reactor, d['host'], int(d['port'])) else: ep = TCP4ServerEndpoint(reactor, int(d['port']), interface=d['host']) if ep: ep.dbus_args = d epl.append(ep) return epl
class XmppService(xmppim.MessageProtocol): def __init__(self, cfg): self.cfg = cfg self.active = {} self.redis = None self.core = UNIXClientEndpoint(reactor, self.cfg.get("xmpp", "dmproc")) self.pooling = task.LoopingCall(self.redis_pooling) @defer.inlineCallbacks def redis_pooling(self): data0 = yield self.redis.hgetall("leela.xmpp") for (key, conn) in list(self.active.iteritems()): if (key not in data0): logger.warn("reaping connection: %s" % (key,)) conn.shutdown() for (key, data1) in data0.iteritems(): data = parser.parse_json(data1) if (key not in self.active): logger.debug("spawning connection: %s: %s" % (key, data["sender"])) conn = Connection(key, xmppim.JID(data["sender"]), data["request"]["select"], self) self.core.connect(conn.factory()) @defer.inlineCallbacks def handle_select(self, request, sender, cc): try: if ((request["select"]["regex"] == "leela.xmpp") and (request["select"]["proc"] == "*")): data0 = yield self.redis.hgetall("leela.xmpp") tmp = [] for (key, data1) in data0.iteritems(): data = parser.parse_json(data1) sql = pp.render_select(data["request"]["select"]["proc"], data["request"]["select"]["regex"]) if (data["sender"] == sender.userhost()): tmp.append({"key": key, "cmd": sql }) cc(200, {"results": tmp}) else: hcode = hashlib.sha512() hcode.update(sender.userhost()) hcode.update(request["select"]["proc"]) hcode.update(request["select"]["regex"]) key = hcode.hexdigest() self.redis.hsetnx("leela.xmpp", key, pp.render_json({"request": request, "sender": sender.userhost()})) except: logger.exception() cc(500, {"reason": "internal server error"}) @defer.inlineCallbacks def handle_delete_all(self, sender, cc): data0 = yield self.redis.hgetall("leela.xmpp") keys = [] for (key, data1) in data0.iteritems(): data = parser.parse_json(data1) if (data["sender"] == sender.userhost()): keys.append({"key": key}) self.redis.hdel("leela.xmpp", key) cc(200, {"results": keys}) @defer.inlineCallbacks def handle_delete_one(self, key, sender, cc): data0 = yield self.redis.hget("leela.xmpp", key) if (data0 is not None): data = parser.parse_json(data0) if (data["sender"] == sender.userhost()): yield self.redis.hdel("leela.xmpp", key) cc(200, {"results": {"key": key}}) else: cc(403, {"reason": "forbidden"}) else: cc(404, {"reason": "not found"}) def handle_delete(self, request, sender, cc): try: key = request["delete"]["key"] if (key is None): self.handle_delete_all(sender, cc) else: self.handle_delete_one(key, sender, cc) except: logger.exception() cc(500, {"reason": "internal server error"}) def handle_request(self, request, sender, cc): if ("select" in request): self.handle_select(request, sender, cc) elif ("delete" in request): self.handle_delete(request, sender, cc) else: cc(400, {"reason": "unknow command"}) def mkcc(self, envelope, debug={}): def f(status, results=None): if (results is None): envelope.addElement("body", content=pp.render_json({"status": status, "debug": debug})) else: msg = dict(results) msg.update({"status": status, "debug": debug}) envelope.addElement("body", content=pp.render_json(msg)) self.send(envelope) return(f) def onMessage(self, message): if (message.body is None): return sender = xmppim.JID(message.getAttribute("from")) req = parser.parse_sql_(unicode(message.body)) debug = {"request": unicode(message.body)} resp = xmppim.Message(recipient = sender).toElement() cc = self.mkcc(resp, debug) if (req in [{}, None]): logger.debug("message [%s] - 400" % message.body) cc(400, {"reason": "parse error"}) else: logger.debug("message [%s] %s - 200" % (message.getAttribute("from"), message.body)) self.handle_request(req, sender, cc) @defer.inlineCallbacks def connectionMade(self): try: self.redis = yield redis.ConnectionPool(self.cfg.get("redis", "host"), self.cfg.getint("redis", "port"), self.cfg.getint("redis", "db"), True) self.pooling.start(5) xmppim.MessageProtocol.connectionMade(self) except: logger.exception() def connectionLost(self, reason): xmppim.MessageProtocol.connectionLost(self, reason) funcs.suppress(self.pooling.stop)() funcs.suppress(self.redis.disconnect)()
def __init__(self, cfg): self.cfg = cfg self.active = {} self.redis = None self.core = UNIXClientEndpoint(reactor, self.cfg.get("xmpp", "dmproc")) self.pooling = task.LoopingCall(self.redis_pooling)
def start(self, transport, klassname, realm): """ Dynamically start an application component to run next to the router in "embedded mode". """ ## dynamically load the application component .. ## try: if self.debug: log.msg("Worker {}: starting class '{}' in realm '{}' ..".format(self._pid, klassname, realm)) import importlib c = klassname.split('.') mod, klass = '.'.join(c[:-1]), c[-1] app = importlib.import_module(mod) SessionKlass = getattr(app, klass) except Exception as e: if self.debug: log.msg("Worker {}: failed to import class - {}".format(e)) raise ApplicationError("crossbar.error.class_import_failed", str(e)) else: ## create a WAMP application session factory ## #from autobahn.twisted.wamp import ApplicationSessionFactory #session_factory = ApplicationSessionFactory() session_factory = ComponentSessionFactory(realm) session_factory.session = SessionKlass ## create a WAMP-over-WebSocket transport client factory ## from autobahn.twisted.websocket import WampWebSocketClientFactory transport_factory = WampWebSocketClientFactory(session_factory, transport['url'], debug = self.debug) transport_factory.setProtocolOptions(failByDrop = False) ## start a WebSocket client from an endpoint ## from twisted.internet import reactor from twisted.internet.endpoints import TCP4ClientEndpoint, SSL4ClientEndpoint, UNIXClientEndpoint from twisted.internet.endpoints import clientFromString from tlsctx import TlsClientContextFactory if False: self._client = clientFromString(reactor, transport['endpoint']) else: try: endpoint_config = transport.get('endpoint') ## a TCP4 endpoint ## if endpoint_config['type'] == 'tcp': ## the host to connect ot ## host = str(endpoint_config['host']) ## the port to connect to ## port = int(endpoint_config['port']) ## connection timeout in seconds ## timeout = int(endpoint_config.get('timeout', 10)) if 'tls' in endpoint_config: ctx = TlsClientContextFactory() ## create a TLS client endpoint ## self._client = SSL4ClientEndpoint(reactor, host, port, ctx, timeout = timeout) else: ## create a non-TLS client endpoint ## self._client = TCP4ClientEndpoint(reactor, host, port, timeout = timeout) ## a Unix Domain Socket endpoint ## elif endpoint_config['type'] == 'unix': ## the path ## path = str(endpoint_config['path']) ## connection timeout in seconds ## timeout = int(endpoint_config['type'].get('timeout', 10)) ## create the endpoint ## self._client = UNIXClientEndpoint(reactor, path, timeout = timeout) else: raise ApplicationError("crossbar.error.invalid_configuration", "invalid endpoint type '{}'".format(endpoint_config['type'])) except Exception as e: log.msg("endpoint creation failed: {}".format(e)) raise e retry = True retryDelay = 1000 def try_connect(): print "Trying to connect .." d = self._client.connect(transport_factory) def success(res): if True or self.debug: log.msg("Worker {}: client connected to router".format(self._pid)) def error(err): log.msg("Worker {}: client failed to connect to router - {}".format(self._pid, err)) if retry: log.msg("Worker {}: retrying in {} ms".format(self._pid, retryDelay)) reactor.callLater(float(retryDelay) / 1000., try_connect) else: log.msg("Worker {}: giving up.".format(seld._pid)) d.addCallbacks(success, error) try_connect()