Пример #1
0
    def install(self):
        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)
        command_client = APIClient(db.get_configure()).get_command_api_client()
        enterprise_id = db.get_enterprise_id()
        device_client = APIClient(db.get_configure()).get_device_api_client()

        if self.app.pargs.device:
            device_name = self.app.pargs.device
            kwargs = {'name': device_name}
            try:
                search_response = device_client.get_all_devices(enterprise_id, limit=1, offset=0, **kwargs)
                if not search_response.results or len(search_response.results) == 0:
                    self.app.log.debug(f'[device-command-install] Device does not exist with name {device_name}')
                    self.app.render(f'Device does not exist with name {device_name}\n')
                    return
                response = search_response.results[0]
                device_id = response.id
            except ApiException as e:
                self.app.log.error(f"[device-command-install] Failed to list devices: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}\n")
                return
        else:
            device = db.get_device()
            if not device or not device.get('id'):
                self.app.log.debug('[device-command-install] There is no active device.')
                self.app.render('There is no active device.\n')
                return

            device_id = device.get('id')

        version_id = self.app.pargs.version
        command_request = CommandRequest(command_args={"app_version": version_id},
                                         command=DeviceCommandEnum.INSTALL.name)
        try:
            response = command_client.run_command(enterprise_id, device_id, command_request)
        except ApiException as e:
            self.app.log.error(f"[device-command-install] Failed to fire the install command: {e}")
            self.app.render(f"ERROR: {parse_error_message(self.app, e)}\n")
            return

        if not self.app.pargs.json:
            renderable = self._command_basic_response(response)
            self.app.render(renderable, format=OutputFormat.TABULATED.value, headers="keys", tablefmt="plain")
        else:
            renderable = self._command_basic_response(response, OutputFormat.JSON)
            self.app.render(renderable, format=OutputFormat.JSON.value)
Пример #2
0
    def set_active(self):
        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)
        device_client = APIClient(db.get_configure()).get_device_api_client()
        enterprise_id = db.get_enterprise_id()

        if self.app.pargs.name:
            device_name = self.app.pargs.name
            kwargs = {'name': device_name}
            try:
                search_response = device_client.get_all_devices(enterprise_id, limit=1, offset=0, **kwargs)
                if not search_response.results or len(search_response.results) == 0:
                    self.app.log.debug(f'[device-active] Device does not exist with name {device_name}')
                    self.app.render(f'Device does not exist with name {device_name}\n')
                    return
                response = search_response.results[0]
                db.set_device({'id': response.id, 'name': response.device_name})
            except ApiException as e:
                self.app.log.error(f"[device-active] Failed to list devices: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}\n")
                return
        else:
            device = db.get_device()
            if device is None or device.get('name') is None:
                self.app.log.debug('[device-active] There is no active device.')
                self.app.render('There is no active device.\n')
                return

            device_id = device.get('id')
            try:
                response = device_client.get_device_by_id(enterprise_id, device_id)
            except ApiException as e:
                self.app.log.error(f"[device-active] Failed to show active device: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}\n")
                return

        if not self.app.pargs.json:
            renderable = self._device_basic_response(response)
            self.app.render(renderable, format=OutputFormat.TABULATED.value, headers="keys", tablefmt="plain")
        else:
            renderable = self._device_basic_response(response, OutputFormat.JSON)
            self.app.render(renderable, format=OutputFormat.JSON.value)
Пример #3
0
    def connect(self):
        """Setup and connect securely via Remote ADB to device"""

        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)

        enterprise_id = db.get_enterprise_id()

        # Remove older certs
        cleanup_certs(self.app)

        # Create new certs
        create_self_signed_cert(local_cert=self.app.local_cert,
                                local_key=self.app.local_key)

        try:
            # Get device
            device_id = None
            if self.app.pargs.device_name:
                device_id = self._fetch_device_by_name(
                    self.app.pargs.device_name)
                self.app.log.debug(
                    f"Device Name: {self.app.pargs.device_name}. Device ID: {device_id}"
                )

            elif db.get_device():
                device_id = db.get_device().get('id')

            else:
                self.app.log.error("[remoteadb-connect] Device not specified!")
                return

            self.app.render(
                "\nInitiating Remote ADB Session. This may take a few seconds...\n"
            )

            # Call SCAPI for establish remote adb connection with device
            remoteadb_id = initiate_remoteadb_connection(
                environment=db.get_configure().get("environment"),
                enterprise_id=enterprise_id,
                device_id=device_id,
                api_key=db.get_configure().get("api_key"),
                client_cert_path=self.app.local_cert,
                log=self.app.log)

            # Poll and fetch the TCP relay's endpoint
            relay_ip, relay_port = fetch_relay_endpoint(
                environment=db.get_configure().get("environment"),
                enterprise_id=enterprise_id,
                device_id=device_id,
                remoteadb_id=remoteadb_id,
                api_key=db.get_configure().get("api_key"),
                log=self.app.log)

            # Poll and fetch the Device's Certificate String
            device_cert = fetch_device_certificate(
                environment=db.get_configure().get("environment"),
                enterprise_id=enterprise_id,
                device_id=device_id,
                remoteadb_id=remoteadb_id,
                api_key=db.get_configure().get("api_key"),
                log=self.app.log)

            # Save Device certificate to disk
            save_device_certificate(self.app.device_cert, device_cert)

            # Setup an SSL connection to TCP relay
            secure_sock = self.setup_ssl_connection(
                host=relay_ip,
                port=relay_port,
                client_cert=self.app.local_cert,
                client_key=self.app.local_key,
                device_cert=self.app.device_cert)

            relay = Relay(relay_conn=secure_sock,
                          relay_addr=secure_sock.getsockname(),
                          log=self.app.log)

            listener_ip, listener_port = relay.get_listener_address()

            title = "Secure ADB Client"
            table = [
                {
                    title:
                    f"Please connect ADB client to the following endpoint: {listener_ip} : {listener_port}"
                },
                {
                    title:
                    f"If adb-tools is installed, please run the command below:\n adb connect {listener_ip}:{listener_port}"
                },
                {
                    title: "Press Ctrl+C to quit! "
                },
            ]

            self.app.render(table,
                            format=OutputFormat.TABULATED.value,
                            headers="keys",
                            tablefmt="plain")

            self.app.log.debug("[remoteadb-connect] Starting Client Mediator")

            relay.accept_connection()
            relay.start_relay()

        except (SecureADBWorkflowError, RemoteADBError) as timeout_exc:
            self.app.log.error(f"[remoteadb-connect] {str(timeout_exc)}")
            self.app.render(
                f"[ERROR] Issue in reaching Esper API Service for connection negotiation!"
            )

        except CaughtSignal as sig:
            self.app.log.debug(
                f"Recieved Signal: {signal.Signals(sig.signum).name}")
            if sig.signum == signal.SIGINT:
                self.app.render("Quitting application...")

        except Exception as exc:
            self.app.log.error(
                f"Failed to establish Secure ADB connection to device: {self.app.pargs.device_name}"
            )
            self.app.log.debug(f"Exception Encountered -> {exc}")

        finally:
            if "relay" in locals():
                relay = locals().get("relay")
                relay.stop_relay()
                metrics = relay.gather_metrics()
                relay.cleanup_connections()

                if metrics.get('started') and metrics.get('stopped'):
                    self.app.render(
                        f"\nSession Duration: {metrics.get('stopped') - metrics.get('started')}"
                    )

                if metrics.get('bytes'):
                    self.app.render(
                        f"\nTotal Data streamed: {metrics.get('bytes')/1024.0} KB\n"
                    )
Пример #4
0
    def latest(self):
        """Command to list status"""
        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)
        device_client = APIClient(db.get_configure()).get_device_api_client()
        enterprise_id = db.get_enterprise_id()

        if self.app.pargs.device:
            device_name = self.app.pargs.device
            kwargs = {'name': device_name}
            try:
                search_response = device_client.get_all_devices(enterprise_id,
                                                                limit=1,
                                                                offset=0,
                                                                **kwargs)
                if not search_response.results or len(
                        search_response.results) == 0:
                    self.app.log.debug(
                        f'[status-latest] Device does not exist with name {device_name}'
                    )
                    self.app.render(
                        f'Device does not exist with name {device_name}')
                    return
                response = search_response.results[0]
                device_id = response.id
            except ApiException as e:
                self.app.log.error(
                    f"[status-latest] Failed to list devices: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
                return
        else:
            device = db.get_device()
            if not device or not device.get('id'):
                self.app.log.debug(
                    '[status-latest] There is no active device.')
                self.app.render('There is no active device.')
                return

            device_id = device.get('id')

        try:
            response = device_client.get_device_event(enterprise_id,
                                                      device_id,
                                                      latest_event=1)
        except ApiException as e:
            self.app.log.error(
                f"[status-latest] Failed to get latest device status: {e}")
            self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
            return

        battery_level = None
        battery_temp = None
        data_download = None
        data_upload = None
        memory_storage = None
        memory_ram = None
        link_speed = None
        signal_strength = None

        if response.results and len(response.results) > 0:
            data = literal_eval(response.results[0].data)
            if data.get("powerManagementEvent") and data.get(
                    "powerManagementEvent").get("batteryStatus"):
                if data.get("powerManagementEvent").get("batteryStatus").get(
                        "batteryLevel"):
                    battery_level = data.get("powerManagementEvent").get(
                        "batteryStatus").get("batteryLevel")

                if data.get("powerManagementEvent").get("batteryStatus").get(
                        "batteryTemperature"):
                    battery_temp = data.get("powerManagementEvent").get(
                        "batteryStatus").get("batteryTemperature")

            if data.get("dataUsageStats"):
                if data.get("dataUsageStats").get("totalDataDownload"):
                    data_download = data.get("dataUsageStats").get(
                        "totalDataDownload")

                if data.get("dataUsageStats").get("totalDataUpload"):
                    data_upload = data.get("dataUsageStats").get(
                        "totalDataUpload")

            if data.get("memoryEvents") and len(data.get("memoryEvents")) > 1 and \
                    data.get("memoryEvents")[1].get("countInMb"):
                memory_storage = data.get("memoryEvents")[1].get("countInMb")

            if data.get("memoryEvents") and len(data.get("memoryEvents")) > 0 and \
                    data.get("memoryEvents")[0].get("countInMb"):
                memory_ram = data.get("memoryEvents")[0].get("countInMb")

            if data.get("networkEvent") and data.get("networkEvent").get(
                    "wifiNetworkInfo"):
                if data.get("networkEvent").get("wifiNetworkInfo").get(
                        "linkSpeed"):
                    link_speed = data.get("networkEvent").get(
                        "wifiNetworkInfo").get("linkSpeed")

                if data.get("networkEvent").get("wifiNetworkInfo").get(
                        "signalStrength"):
                    signal_strength = data.get("networkEvent").get(
                        "wifiNetworkInfo").get("signalStrength")

        if not self.app.pargs.json:
            title = "TITLE"
            details = "DETAILS"
            renderable = [{
                title: 'battery_level',
                details: battery_level
            }, {
                title: 'battery_temperature',
                details: battery_temp
            }, {
                title: 'data_download',
                details: data_download
            }, {
                title: 'data_upload',
                details: data_upload
            }, {
                title: 'memory_storage',
                details: memory_storage
            }, {
                title: 'memory_ram',
                details: memory_ram
            }, {
                title: 'link_speed',
                details: link_speed
            }, {
                title: 'signal_strength',
                details: signal_strength
            }]

            self.app.render(renderable,
                            format=OutputFormat.TABULATED.value,
                            headers="keys",
                            tablefmt="plain")
        else:
            renderable = {
                'battery_level': battery_level,
                'battery_temperature': battery_temp,
                'data_download': data_download,
                'data_upload': data_upload,
                'memory_storage': memory_storage,
                'memory_ram': memory_ram,
                'link_speed': link_speed,
                'signal_strength': signal_strength
            }
            self.app.render(renderable, format=OutputFormat.JSON.value)
Пример #5
0
    def list(self):
        """Command to list installs"""
        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)
        device_client = APIClient(db.get_configure()).get_device_api_client()
        enterprise_id = db.get_enterprise_id()

        if self.app.pargs.device:
            device_name = self.app.pargs.device
            kwargs = {'name': device_name}
            try:
                search_response = device_client.get_all_devices(enterprise_id,
                                                                limit=1,
                                                                offset=0,
                                                                **kwargs)
                if not search_response.results or len(
                        search_response.results) == 0:
                    self.app.log.debug(
                        f'[installs-list] Device does not exist with name {device_name}'
                    )
                    self.app.render(
                        f'Device does not exist with name {device_name}')
                    return
                response = search_response.results[0]
                device_id = response.id
            except ApiException as e:
                self.app.log.error(
                    f"[installs-list] Failed to list devices: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
                return
        else:
            device = db.get_device()
            if not device or not device.get('id'):
                self.app.log.debug(
                    '[installs-list] There is no active device.')
                self.app.render('There is no active device.')
                return

            device_id = device.get('id')

        app_name = self.app.pargs.appname
        package_name = self.app.pargs.package
        install_state = self.app.pargs.state
        limit = self.app.pargs.limit
        offset = self.app.pargs.offset

        kwargs = {}
        if app_name:
            kwargs['application_name'] = app_name

        if package_name:
            kwargs['package_name'] = package_name

        if install_state:
            kwargs['install_state'] = install_state

        try:
            response = device_client.get_app_installs(enterprise_id,
                                                      device_id,
                                                      limit=limit,
                                                      offset=offset,
                                                      **kwargs)
        except ApiException as e:
            self.app.log.error(f"[installs-list] Failed to list installs: {e}")
            self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
            return

        self.app.render(f"Total Number of Installs: {response.count}")
        if not self.app.pargs.json:
            installs = []

            label = {
                'id': "ID",
                'application_name': "APPLICATION",
                'package_name': "PACKAGE",
                'version_code': "VERSION",
                'install_state': "STATE"
            }

            for install in response.results:
                installs.append({
                    label['id']:
                    install.id,
                    label['application_name']:
                    install.application.application_name,
                    label['package_name']:
                    install.application.package_name,
                    label['version_code']:
                    install.application.version.version_code,
                    label['install_state']:
                    install.install_state
                })
            self.app.render(installs,
                            format=OutputFormat.TABULATED.value,
                            headers="keys",
                            tablefmt="plain")
        else:
            installs = []
            for install in response.results:
                installs.append({
                    'id': install.id,
                    'application_name': install.application.application_name,
                    'package_name': install.application.package_name,
                    'version_code': install.application.version.version_code,
                    'install_state': install.install_state
                })
            self.app.render(installs, format=OutputFormat.JSON.value)
Пример #6
0
    def wipe(self):
        validate_creds_exists(self.app)
        db = DBWrapper(self.app.creds)
        command_client = APIClient(db.get_configure()).get_command_api_client()
        enterprise_id = db.get_enterprise_id()
        device_client = APIClient(db.get_configure()).get_device_api_client()

        if self.app.pargs.device:
            device_name = self.app.pargs.device
            kwargs = {'name': device_name}
            try:
                search_response = device_client.get_all_devices(enterprise_id,
                                                                limit=1,
                                                                offset=0,
                                                                **kwargs)
                if not search_response.results or len(
                        search_response.results) == 0:
                    self.app.log.debug(
                        f'[device-command-wipe] Device does not exist with name {device_name}'
                    )
                    self.app.render(
                        f'Device does not exist with name {device_name}')
                    return
                response = search_response.results[0]
                device_id = response.id
            except ApiException as e:
                self.app.log.error(
                    f"[device-command-wipe] Failed to list devices: {e}")
                self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
                return
        else:
            device = db.get_device()
            if not device or not device.get('id'):
                self.app.log.debug(
                    '[device-command-wipe] There is no active device.')
                self.app.render('There is no active device.')
                return

            device_id = device.get('id')

        external_storage = self.app.pargs.external_storage
        frp = self.app.pargs.frp

        if external_storage is None:
            self.app.log.info(
                '[device-command-wipe] External storage value is empty')
            self.app.render('External storage value is empty')

        if frp is None:
            self.app.log.info(
                '[device-command-wipe] Factory reset production value is empty'
            )
            self.app.render('Factory reset production value is empty')

        command_request = CommandRequest(command_args={
            "wipe_external_storage": external_storage,
            'wipe_FRP': frp
        },
                                         command=DeviceCommandEnum.WIPE.name)
        try:
            response = command_client.run_command(enterprise_id, device_id,
                                                  command_request)
        except ApiException as e:
            self.app.log.error(
                f"[device-command-wipe] Failed to fire the wipe command: {e}")
            self.app.render(f"ERROR: {parse_error_message(self.app, e)}")
            return

        if not self.app.pargs.json:
            renderable = self._command_basic_response(response)
            self.app.render(renderable,
                            format=OutputFormat.TABULATED.value,
                            headers="keys",
                            tablefmt="plain")
        else:
            renderable = self._command_basic_response(response,
                                                      OutputFormat.JSON)
            self.app.render(renderable, format=OutputFormat.JSON.value)