def test_banner(self): banner = "Welcome stranger!" server = backdoor.BackdoorServer(('127.0.0.1', 0), banner=banner) server.start() try: conn = socket.create_connection(('127.0.0.1', server.server_port)) response = read_until(conn, '>>> ') self.assertEqual(response[:len(banner)], banner) finally: server.stop()
def test_builtins(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() try: conn = socket.create_connection(('127.0.0.1', server.server_port)) read_until(conn, '>>> ') conn.sendall('locals()["__builtins__"]\r\n') response = read_until(conn, '>>> ') self.assertTrue(len(response) < 300, msg="locals() unusable: %s..." % response[:100]) finally: server.stop()
def test_quit(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() try: conn = create_connection(('127.0.0.1', server.server_port)) read_until(conn, '>>> ') conn.sendall('quit()\r\n') line = conn.makefile('r').read() self.assertEqual(line, '') finally: server.stop()
def test_sys_exit(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() try: conn = socket.create_connection(('127.0.0.1', server.server_port)) read_until(conn, '>>> ') conn.sendall('import sys; sys.exit(0)\r\n') line = conn.makefile().read() self.assertEqual(line, '') finally: server.stop()
def test_banner(self): banner = "Welcome stranger!" # native string server = backdoor.BackdoorServer(('127.0.0.1', 0), banner=banner) server.start() try: conn = create_connection(('127.0.0.1', server.server_port)) response = read_until(conn, b'>>> ') self.assertEqual(response[:len(banner)], banner, response) conn.close() finally: server.stop()
def test_sys_exit(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() try: conn = create_connection(('127.0.0.1', server.server_port)) read_until(conn, b'>>> ') conn.sendall(b'import sys; sys.exit(0)\r\n') line = readline(conn) self.assertEqual(line, '') finally: conn.close() server.stop()
def test(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() def connect(): conn = socket.create_connection(('127.0.0.1', server.server_port)) read_until(conn, '>>> ') conn.sendall('2+2\r\n') line = conn.makefile().readline() assert line.strip() == '4', repr(line) jobs = [gevent.spawn(connect) for _ in xrange(10)] gevent.joinall(jobs) server.close()
def test_quit(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() conn = None try: conn = create_connection(('127.0.0.1', server.server_port)) read_until(conn, '>>> ') conn.sendall(b'quit()\r\n') line = readline(conn) self.assertEqual(line, '') finally: if conn is not None: conn.close() server.stop()
def test_builtins(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() conn = None try: conn = create_connection(('127.0.0.1', server.server_port)) read_until(conn, b'>>> ') conn.sendall(b'locals()["__builtins__"]\r\n') response = read_until(conn, '>>> ') self.assertTrue(len(response) < 300, msg="locals() unusable: %s..." % response) finally: if conn is not None: conn.close() server.stop()
def test(self): server = backdoor.BackdoorServer(('127.0.0.1', 0)) server.start() def connect(): conn = create_connection(('127.0.0.1', server.server_port)) try: read_until(conn, '>>> ') conn.sendall(b'2+2\r\n') line = readline(conn) self.assertEqual(line.strip(), '4', repr(line)) finally: conn.close() try: jobs = [gevent.spawn(connect) for _ in xrange(10)] gevent.joinall(jobs, raise_error=True) finally: server.close()
def _make_server(self, *args, **kwargs): assert self._server is None self._server = backdoor.BackdoorServer(('127.0.0.1', 0), *args, **kwargs) self._close_on_teardown(self._server.stop) self._server.start()
def _make_server(self, *args, **kwargs): assert self._server is None self._server = backdoor.BackdoorServer(DEFAULT_BIND_ADDR_TUPLE, *args, **kwargs) self._close_on_teardown(self._server.stop) self._server.start()
def _make_and_start_server(self, *args, **kwargs): server = backdoor.BackdoorServer(DEFAULT_BIND_ADDR_TUPLE, *args, **kwargs) server.start() return server
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) #sock.settimeout(5) sock.connect((app.remote_host, app.remote_port)) return sock if __name__ == "__main__": host, port = get_args() app.debug = True app.connected_mode = True if host and port else False app.sock = None app.last_read = None try: if app.connected_mode: app.remote_host = host app.remote_port = port app.tail = gevent.spawn(tail) manhole = backdoor.BackdoorServer(("127.0.0.1", 1337), locals={"app": app}) manhole.start() server = WSGIServer(("", 5000), app) server.serve_forever() except KeyboardInterrupt: if app.sock: app.sock.close() manhole.close() server.close()
def main(command=None): """ Main entrypoint """ auth_manager = None repl_server_handle = None # Used for Command.REPLServer if command: # Take passed command and append actual cmdline cmdline_arguments = sys.argv[1:] cmdline_arguments.insert(0, command) else: cmdline_arguments = None args = parse_arguments(cmdline_arguments) handle_logging_setup(args) LOGGER.debug('Parsed arguments: {0}'.format(args)) command = args.command LOGGER.debug('Chosen command: {0}'.format(command)) if command == Commands.RESTServer: LOGGER.info( 'Make sure you used the dedicated \'xbox-rest-server\' script' ' to start the REST server!') elif 'interactive' in args and args.interactive and \ (args.address or args.liveid): LOGGER.error( 'Flag \'--interactive\' is incompatible with' ' providing an IP address (--address) or LiveID (--liveid) explicitly' ) sys.exit(ExitCodes.ArgParsingError) elif args.liveid and args.address: LOGGER.warning( 'You passed --address AND --liveid: Will only use that specific' 'combination!') elif command == Commands.PowerOff and args.all and (args.liveid or args.address): LOGGER.error( 'Poweroff with --all flag + explicitly provided LiveID / IP address makes no sense' ) sys.exit(ExitCodes.ArgParsingError) elif command == Commands.PowerOff and args.interactive and args.all: LOGGER.error('Combining args --all and --interactive not supported') sys.exit(ExitCodes.ArgParsingError) print('Xbox SmartGlass main client started') if command == Commands.RESTServer: """ REST Server """ if args.port == 0: LOGGER.info('No defaults provided, ' 'Setting REST server port to {0}'.format( REST_DEFAULT_SERVER_PORT)) args.port = REST_DEFAULT_SERVER_PORT print('Xbox Smartglass REST server started on {0}:{1}'.format( args.bind, args.port)) flask_app.token_file = args.tokens server = rest_pywsgi.WSGIServer((args.bind, args.port), flask_app) server.serve_forever() sys.exit(ExitCodes.OK) elif command == Commands.TUI: """ Text user interface (powered by urwid) """ # Removing stream handlers to not pollute TUI for h in [ sh for sh in logging.root.handlers if isinstance(sh, logging.StreamHandler) ]: LOGGER.debug( 'Removing StreamHandler {0} from root logger'.format(h)) logging.root.removeHandler(h) sys.exit( tui.run_tui(args.consoles, args.address, args.liveid, args.tokens, args.refresh)) elif 'tokens' in args: """ Do Xbox live authentication """ LOGGER.debug( 'Command {0} supports authenticated connection'.format(command)) try: auth_manager = do_authentication(args.tokens, args.refresh) except AuthenticationException: LOGGER.exception('Authentication failed!') LOGGER.error("Please re-run xbox-authenticate to get a fresh set") sys.exit(ExitCodes.AuthenticationError) elif command == Commands.PowerOn: """ Powering up console """ if not args.liveid: LOGGER.error('No LiveID (--liveid) provided for power on!') sys.exit(ExitCodes.ArgParsingError) LOGGER.info('Sending poweron packet for LiveId: {0} to {1}'.format( args.liveid, 'IP: ' + args.address if args.address else '<MULTICAST>')) Console.power_on(args.liveid, args.address, tries=10) sys.exit(0) """ Discovery """ discovered = cli_discover_consoles(args) if command == Commands.Discover: """ Simply print discovered consoles """ print("Discovered %d consoles: " % len(discovered)) for console in discovered: print(" %s" % console) sys.exit(ExitCodes.OK) elif command == Commands.PowerOff and args.all: """ Early call for poweroff --all """ """Powering off all discovered consoles""" for c in discovered: print('Powering off console {0}'.format(c)) c.power_off() sys.exit(ExitCodes.OK) """ Choosing/filtering a console from the discovered ones """ console = None if args.interactive: LOGGER.debug('Starting interactive console choice') console = choose_console_interactively(discovered) elif len(discovered) == 1: LOGGER.debug('Choosing sole console, no user interaction required') console = discovered[0] elif len(discovered) > 1: LOGGER.error('More than one console was discovered and no exact' ' connection parameters were provided') if not console: LOGGER.error('Choosing a console failed!') sys.exit(ExitCodes.ConsoleChoice) LOGGER.info('Choosen target console: {0}'.format(console)) LOGGER.debug('Setting console callbacks') console.on_device_status += \ lambda x: LOGGER.info('Device status: {0}'.format(x)) console.on_connection_state += \ lambda x: LOGGER.info('Connection state: {0}'.format(x)) console.on_pairing_state += \ lambda x: LOGGER.info('Pairing state: {0}'.format(x)) console.on_console_status += \ lambda x: LOGGER.info('Console status: {0}'.format(x)) console.on_timeout += \ lambda x: LOGGER.error('Timeout occured!') or sys.exit(1) userhash = auth_manager.userinfo.userhash xtoken = auth_manager.xsts_token LOGGER.debug('Authentication info:') LOGGER.debug('Userhash: {0}'.format(userhash)) LOGGER.debug('XToken: {0}'.format(xtoken)) LOGGER.info('Attempting connection...') state = console.connect(userhash, xtoken.jwt) if state != ConnectionState.Connected: LOGGER.error('Connection failed! Console: {0}'.format(console)) sys.exit(1) # FIXME: Waiting explicitly LOGGER.info('Connected to console: {0}'.format(console)) LOGGER.debug('Waiting a second before proceeding...') console.wait(1) if command == Commands.PowerOff: """ Power off (single console) """ print('Powering off console {0}'.format(console)) console.power_off() sys.exit(ExitCodes.OK) elif command == Commands.REPL or \ command == Commands.REPLServer: banner = 'You are connected to the console @ {0}\n'\ .format(console.address) banner += 'Type in \'console\' to acccess the object\n' banner += 'Type in \'exit()\' to quit the application' scope_vars = {'console': console} if command == Commands.REPL: LOGGER.info('Starting up local REPL console') repl_local = InteractiveConsole(locals=scope_vars) repl_local.interact(banner) else: if args.port == 0: LOGGER.info('No defaults provided, ' 'Setting REPL server port to {0}'.format( REPL_DEFAULT_SERVER_PORT)) args.port = REPL_DEFAULT_SERVER_PORT startinfo = 'Starting up REPL server @ {0}:{1}'.format( args.bind, args.port) print(startinfo) LOGGER.info(startinfo) repl_server_handle = backdoor.BackdoorServer(listener=(args.bind, args.port), banner=banner, locals=scope_vars) elif command == Commands.FalloutRelay: """ Fallout 4 relay """ print('Starting Fallout 4 relay service...') console.add_manager(TitleManager) console.title.on_connection_info += fallout4_relay.on_connection_info console.start_title_channel(title_id=fallout4_relay.FALLOUT_TITLE_ID) print('Fallout 4 relay started') elif command == Commands.GamepadInput: """ Gamepad input """ print('Starting gamepad input handler...') console.add_manager(manager.InputManager) gamepad_input.input_loop(console) elif command == Commands.TextInput: """ Text input """ print('Starting text input handler...') console.add_manager(manager.TextManager) console.text.on_systemtext_configuration += text_input.on_text_config console.text.on_systemtext_input += functools.partial( text_input.on_text_input, console) console.text.on_systemtext_done += text_input.on_text_done LOGGER.debug('Installing gevent SIGINT handler') signal.signal(signal.SIGINT, lambda *a: console.protocol.stop()) if repl_server_handle: LOGGER.debug('Starting REPL server protocol') LOGGER.debug('Starting console.protocol.serve_forever()') console.protocol.serve_forever() LOGGER.debug('Protocol serving exited') if repl_server_handle: LOGGER.debug('Stopping REPL server protocol') repl_server_handle.stop()